Ethereal-dev: [ethereal-dev] My diffs for pseudo real-time capture

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: John McDermott <jjm@xxxxxxxxxx>
Date: Thu, 29 Apr 99 15:13:52
Attached are the CVS diffs for the changes I made.  See my last message for 
further details.

Important note!: The execlp() when you fork() calls "ethereal".  Therefore 
it will use the first ethereal in your path.  Be sure the new one is the 
first in your path, or it won't work correctly.  You can change capture.c 
if you would like different behavior.

To get pseudo real-time display:
================================
The way I did pseudo-real-time display is to have an option which forks a 
child for capture.  It also pre-loads the file name into the Open dialog 
box so the user can get it easily.  I also added a sync option so that if 
you reload the file, it signals the capturing child to fflush the buffer.  
It will therefore sometimes show one more packet in the window than the 
capture counts window does because that window does not refresh the count 
every time.  This is probably fixed if one uses the linux-patched (I'm 
using Linux 2.2.5 with libpcap 0.4) pcap.  I haven't got that, yet.  I 
thought I saw the location on the list, but now I can't find that message.

To use the real-time scheme I have set up:
	ethereal -F	or
	ethereal -F -S

then start the capture as usual.  After at least one packet has been 
captured, do a File/Open.  When you want to see more packets, do 
File/Reload (there is an ugly 2 sec wait for synchronization).

You can also use the changes to make an ethereal which captures n packets 
and quits (with -Q) etc.

--john

-------------------------------------
Name: John McDermott
VOICE: +1 505/377-6293 FAX +1 505/377-6313
E-mail: John McDermott <jjm@xxxxxxxxxx>
Writer and Computer Consultant
-------------------------------------
===================================================================
RCS file: /cvsroot/ethereal/aclocal.m4,v
retrieving revision 1.7
diff -r1.7 aclocal.m4
339d338
<   char *tmp_version;
343,345c342
<   /* HP/UX 9 (%@#!) writes to sscanf strings */
<   tmp_version = g_strdup("$min_gtk_version");
<   if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
---
>   if (sscanf("$min_gtk_version", "%d.%d.%d", &major, &minor, &micro) != 3) {
Index: capture.c
===================================================================
RCS file: /cvsroot/ethereal/capture.c,v
retrieving revision 1.21
diff -r1.21 capture.c
72a73,76
> extern int fork_mode;
> int fork_child;
> extern int quit_after_cap;
> 
86a91,94
> /* how often to force an fflush */
> #define DUMP_FREQ 4
> FILE *dump_file_handle;
> 
340c348
<     atoi(g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(count_cb)->entry))));
---
>     atoi( g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(count_cb)->entry))));
357c365,388
<   capture();
---
>   if( fork_mode ){	/*  use fork() for capture */
>     char ssnap[24];
>     char scount[24];	/* need a constant for len of numbers */
> 
>     sprintf(ssnap,"%d",cf.snap); /* in liu of itoa */
>     sprintf(scount,"%d",cf.count);
>     if((fork_child = fork()) == 0){
>       /* args: -k -- capture
>        * -i interface specification
>        * -w file to write
>        * -c count to capture
>        * -Q quit after capture (forces -k)
>        * -s snaplen
>        * should add  -b -m -t from this invocation: TODO
>        */
> 	  execlp("ethereal","ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
> 	    "-c",scount,"-s", ssnap,0);
>     }
>     else {
>        cf.filename = cf.save_file;
>     }
>   }
>   else
>     capture();
403a435,437
>     /* save the file handle for flushing when a SIGUSR1 arrives */
>     dump_file_handle = (FILE *)ld.pdh; 
> 
506a541,545
>   if( quit_after_cap ){
>     /* DON'T unlink the save file.  Presumably someone wants it. */
>     gtk_exit(0);
>   }
> 
536a576
>   static int dump_count = 0;
545a586,592
>   /* flush every DUMP_FREQ times */
>   
>   if ( !dump_count  ){
> 	fflush((FILE *)ld->pdh);
>   }
>   dump_count = (dump_count + 1) % DUMP_FREQ;
> 
Index: configure
===================================================================
RCS file: /cvsroot/ethereal/configure,v
retrieving revision 1.19
diff -r1.19 configure
1157d1156
<   char *tmp_version;
1161,1163c1160
<   /* HP/UX 9 (%@#!) writes to sscanf strings */
<   tmp_version = g_strdup("$min_gtk_version");
<   if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
---
>   if (sscanf("$min_gtk_version", "%d.%d.%d", &major, &minor, &micro) != 3) {
1213c1210
< if { (eval echo configure:1214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
---
> if { (eval echo configure:1211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
1247c1244
< #line 1248 "configure"
---
> #line 1245 "configure"
1257c1254
< if { (eval echo configure:1258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
---
> if { (eval echo configure:1255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
1298c1295
< echo "configure:1299: checking for extraneous pcap header directories" >&5
---
> echo "configure:1296: checking for extraneous pcap header directories" >&5
1318c1315
< echo "configure:1319: checking how to run the C preprocessor" >&5
---
> echo "configure:1316: checking how to run the C preprocessor" >&5
1333c1330
< #line 1334 "configure"
---
> #line 1331 "configure"
1339c1336
< { (eval echo configure:1340: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1337: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1350c1347
< #line 1351 "configure"
---
> #line 1348 "configure"
1356c1353
< { (eval echo configure:1357: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1354: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1380c1377
< echo "configure:1381: checking for net/bpf.h" >&5
---
> echo "configure:1378: checking for net/bpf.h" >&5
1385c1382
< #line 1386 "configure"
---
> #line 1383 "configure"
1390c1387
< { (eval echo configure:1391: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1414c1411
< echo "configure:1415: checking for pcap.h" >&5
---
> echo "configure:1412: checking for pcap.h" >&5
1419c1416
< #line 1420 "configure"
---
> #line 1417 "configure"
1424c1421
< { (eval echo configure:1425: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1422: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1447c1444
< echo "configure:1448: checking for pcap_open_offline in -lpcap" >&5
---
> echo "configure:1445: checking for pcap_open_offline in -lpcap" >&5
1455c1452
< #line 1456 "configure"
---
> #line 1453 "configure"
1466c1463
< if { (eval echo configure:1467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
---
> if { (eval echo configure:1464: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
1497c1494
< echo "configure:1498: checking whether to include wiretap library" >&5
---
> echo "configure:1495: checking whether to include wiretap library" >&5
1539c1536
< echo "configure:1540: checking whether to enable ipv6 name resolution if available" >&5
---
> echo "configure:1537: checking whether to enable ipv6 name resolution if available" >&5
1549c1546
< echo "configure:1550: checking ipv6 stack type" >&5
---
> echo "configure:1547: checking ipv6 stack type" >&5
1554c1551
< #line 1555 "configure"
---
> #line 1552 "configure"
1574c1571
< #line 1575 "configure"
---
> #line 1572 "configure"
1594c1591
< #line 1595 "configure"
---
> #line 1592 "configure"
1614c1611
< #line 1615 "configure"
---
> #line 1612 "configure"
1632c1629
< #line 1633 "configure"
---
> #line 1630 "configure"
1681c1678
< echo "configure:1682: checking for ANSI C header files" >&5
---
> echo "configure:1679: checking for ANSI C header files" >&5
1686c1683
< #line 1687 "configure"
---
> #line 1684 "configure"
1694c1691
< { (eval echo configure:1695: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1711c1708
< #line 1712 "configure"
---
> #line 1709 "configure"
1729c1726
< #line 1730 "configure"
---
> #line 1727 "configure"
1750c1747
< #line 1751 "configure"
---
> #line 1748 "configure"
1761c1758
< if { (eval echo configure:1762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
---
> if { (eval echo configure:1759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
1788c1785
< echo "configure:1789: checking for $ac_hdr" >&5
---
> echo "configure:1786: checking for $ac_hdr" >&5
1793c1790
< #line 1794 "configure"
---
> #line 1791 "configure"
1798c1795
< { (eval echo configure:1799: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1796: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1829c1826
< echo "configure:1830: checking for $ac_hdr" >&5
---
> echo "configure:1827: checking for $ac_hdr" >&5
1834c1831
< #line 1835 "configure"
---
> #line 1832 "configure"
1839c1836
< { (eval echo configure:1840: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
---
> { (eval echo configure:1837: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
1872c1869
< echo "configure:1873: checking for sa_len in struct sockaddr" >&5
---
> echo "configure:1870: checking for sa_len in struct sockaddr" >&5
1877c1874
< #line 1878 "configure"
---
> #line 1875 "configure"
1885c1882
< if { (eval echo configure:1886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
---
> if { (eval echo configure:1883: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
1908c1905
< echo "configure:1909: checking whether byte ordering is bigendian" >&5
---
> echo "configure:1906: checking whether byte ordering is bigendian" >&5
1915c1912
< #line 1916 "configure"
---
> #line 1913 "configure"
1926c1923
< if { (eval echo configure:1927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
---
> if { (eval echo configure:1924: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
1930c1927
< #line 1931 "configure"
---
> #line 1928 "configure"
1941c1938
< if { (eval echo configure:1942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
---
> if { (eval echo configure:1939: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
1961c1958
< #line 1962 "configure"
---
> #line 1959 "configure"
1974c1971
< if { (eval echo configure:1975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
---
> if { (eval echo configure:1972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
2000c1997
< echo "configure:2001: checking whether ${CC-cc} needs -traditional" >&5
---
> echo "configure:1998: checking whether ${CC-cc} needs -traditional" >&5
2006c2003
< #line 2007 "configure"
---
> #line 2004 "configure"
2024c2021
< #line 2025 "configure"
---
> #line 2022 "configure"
2046c2043
< echo "configure:2047: checking for socket" >&5
---
> echo "configure:2044: checking for socket" >&5
2051c2048
< #line 2052 "configure"
---
> #line 2049 "configure"
2074c2071
< if { (eval echo configure:2075: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
---
> if { (eval echo configure:2072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
2100c2097
< echo "configure:2101: checking for snprintf" >&5
---
> echo "configure:2098: checking for snprintf" >&5
2105c2102
< #line 2106 "configure"
---
> #line 2103 "configure"
2128c2125
< if { (eval echo configure:2129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
---
> if { (eval echo configure:2126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
Index: ethereal.c
===================================================================
RCS file: /cvsroot/ethereal/ethereal.c,v
retrieving revision 1.31
diff -r1.31 ethereal.c
57a58,59
> #include <signal.h>
> #include <posix1_lim.h>
99a102,108
> int sync_mode;	/* allow sync */
> 
> int fork_mode;	/* fork a child to do the capture */
> extern int fork_child;
> int quit_after_cap; /* Makes a "capture only mode". Implies -k */
> extern FILE *dump_file_handle;
> 
284c293,296
<   gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), "");
---
>   if( fork_mode && (cf.save_file != NULL) )
>     gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), cf.save_file);
>   else
>     gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), "");
396a409,430
>   /* JJM */
> 
>   /* MUST check fork_mode to see 1) if we have a "fork_child" value, and 2) if
>    * the process will catch the signal
>    */
>   if( sync_mode && fork_mode){
>     /* first, see if the child is still there */
>     if( !kill(fork_child, 0)){
>       /* we can talk to our child */
>       kill(fork_child, SIGUSR1);
>       /* wait for the file to be written.  Probably should pass my pid to child so it
>        * can signal us back when it is done.  Then our handler could emit a gtk signal
>        * to force reloading.  As it stands I am hoping that we can make this threaded
>        * (using gtk or pthreads) and hence not need this ugliness.
>        */
> 
>       /* might cause trouble: both sleep and the itimer use SIGALRM.  We use
>        * SIGALRM for dns timeouts.
>        */
>       sleep(2); /* not long enough under heavy load */
>     }
>   }
494,497c528
<     if (cf.save_file)
<       capture();
<     else
<       capture();
---
>     capture();
520a552,561
> /* if we get SIGUSR1 flush the buffer.  Allows sync by someone watching our dump */
> void
> flushit (int sig)
> {
>     if(dump_file_handle)
>         fflush(dump_file_handle);
>     signal(SIGUSR1, flushit);
> }
> 
> 
547a589
> 
549a592
>   
587c630
<   while ((opt = getopt(argc, argv, "b:B:c:hi:m:nP:r:s:t:T:w:v")) != EOF) {
---
>   while ((opt = getopt(argc, argv, "b:B:c:Fhi:km:nP:Qr:Ss:t:T:w:v")) != EOF) {
597a641,643
>       case 'F':	       /* Fork to capture */
>         fork_mode = 1;
>         break;
616a663,666
>       case 'Q':        /* Quit after capture (just capture to file) */
>         quit_after_cap = 1;
>         start_capture = 1;  /*** -Q implies -k !! ***/
>         break;
622a673,675
>       case 'S':        /* "Sync" mode: used for following file ala tail -f */
>         sync_mode = 1;
>         break;
649a703,705
> 
>   if( start_capture)
>     signal(SIGUSR1, flushit); /* catch the flush signal */