On 2/27/06, Mikhail Manuylov <[EMAIL PROTECTED]> wrote:
>
> I really glad to report that I've ported some necessary bits from pflogd
> to implement apped feature in tcpdump.
> No changes were made in tcpdump sources yet ( i.e. we use same -w flag),
> but libpcap's savefile.c
> I've added new function pcap_scan_dump() that's intended to be used for
> pcap_setup_dump() ( which is called from pcap_open_dump()).
> I've already made some testing and found a bug ( or maybe misfeature ):
> this implementation can't change snaplen to snaplen stored in header of dump
> file ( we need to call pcap_compile() && pcap_setfilter() if header snaplen
> not equal to default/command line supplied). In pflogd that function (called
> scan_dump()) implemented in daemon, so this behaviour is possible ( we have
> access to all external variables and stuff).
> So here's the main question: is there any other way ( except to mentioned
> above) to change snaplen on the fly?
> See attached patch.


I've temporarly changed behaviour:  now  you need to restart tcpdump with
correct snaplen to append to file. Crock but works.
See new attached patch.

On 2/21/06, Mikhail Manuylov <[EMAIL PROTECTED]> wrote:
> >
> > On 2/20/06, Christian Kreibich <[EMAIL PROTECTED]> wrote:
> > >
> > > On Thu, 2006-02-16 at 12:42 -0800, Guy Harris wrote:
> > > >
> > > > Require read and write access for appending, open for reading and
> > > > writing, read the header, make sure the link-layer type and snapshot
> > > > length are the same (and fail if they're not), and then seek to the
> > > > end and start writing.
> > >
> > > And check whether the last packet has indeed been written out in its
> > > entirety, otherwise pcap header corruption will occur at the append
> > > spot.
> > >
> > > I'm really looking forward to seeing this in pcap itself. If you need
> > > it
> > > today, use pcapnav:
> > >
> > > http://netdude.sourceforge.net/doco/libpcapnav/pcapnav-pcapnav.html#PCAPNAV-DUMP-OPEN
> > >
> > >
> > > Cheers,
> > > Christian.
> > > --
> > >
> > >
> > Last days I have been investigating pflogd code, a daemon which has
> > implemented feature of log appending with buffering and all necessary
> > checks. pflogd was written by OpenBSD developers and then ported to FreeBSD
> > and perhaps NetBSD. It looks a bit sophisticated for me, cause there are
> > also implementation of privelege separation with local socket and other
> > stuff. Now I'm going to look at tcpdump code towards porting some code from
> > pflogd there (license is BSD too).
> > I have a question about version of tcpdump I shall change and then send
> > patch to [EMAIL PROTECTED] Were there any major changes between 3.9.3 and 
> > 3.9.4or maybe I should checkout current branch from cvs repository?
> >
> > I see pflogd as tcpdump with very redundant feature set (no printing
> > features at all), but for dumping working with binary data it's perfect.
> > Here some features I'd like to see in tcpdump ported from pflogd:
> > 1) daemonizing when dumping
> > 2) checking integrity of existing dumpfile
> > 3) mess with different snaplength
> > 4) privelege separation while dumping
> > --
> > Truly yours, Mikhail Manuilov
>
>
> --
> Truly yours, Mikhail Manuilov
>



--
С уважением, Михаил Мануйлов
Truly yours, Mikhail Manuilov
diff -ur libpcap-0.9.4_orig/savefile.c 
/usr/ports/distfiles/libpcap-0.9.4/savefile.c
--- libpcap-0.9.4_orig/savefile.c       Tue Aug 30 01:05:45 2005
+++ /usr/ports/distfiles/libpcap-0.9.4/savefile.c       Mon Feb 27 17:18:17 2006
@@ -42,6 +42,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 
 #include "pcap-int.h"
 
@@ -1180,10 +1181,87 @@
        (void)fwrite((char *)sp, h->caplen, 1, f);
 }
 
+/*
+ * Stolen from pflogd ( OpenBSD packet filter logger daemon )
+ *
+ * Must read the file, compare the header against our new
+ * options (in particular, snaplen) and adjust our options so
+ * that we generate a correct file. Furthermore, check the file
+ * for consistency so that we can append safely.
+ *
+ * XXX this may take a long time for large dumps.
+*/
+int
+pcap_scan_dump(pcap_t *p, int linktype, FILE *f, off_t size, const char *fname)
+{
+       struct pcap_file_header hdr;
+       struct pcap_sf_pkthdr ph;
+       off_t pos;
+       
+       (void) fseek(f, 0L, SEEK_SET);
+
+       if (fread((char *)&hdr, sizeof(hdr), 1, f) != 1) {
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                               "Error: File %s has short file header",
+                       fname);
+               return (1);
+       }
+
+       if (hdr.magic != TCPDUMP_MAGIC ||
+           hdr.version_major != PCAP_VERSION_MAJOR ||
+           hdr.version_minor != PCAP_VERSION_MINOR ||
+           hdr.linktype != linktype ||
+           hdr.snaplen > 65535) {
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                               "%s: Invalid/incompatible dump file, move it 
away",
+                       fname);
+               return (1);
+       }
+
+       pos = sizeof(hdr);
+
+       while (!feof(f)) {
+               off_t len = fread((char *)&ph, 1, sizeof(ph), f);
+               if (len == 0)
+                       break;
+
+               if (len != sizeof(ph))
+                       goto error;
+               if (ph.caplen > hdr.snaplen || ph.caplen > 65535)
+                       goto error;
+               pos += sizeof(ph) + ph.caplen;
+               if (pos > size)
+                       goto error;
+               fseek(f, ph.caplen, SEEK_CUR);
+       }
+
+       if (pos != size)
+               goto error;
+       
+       if (hdr.snaplen != p->snapshot) {
+               
+               /* FIXME XXX Change snaplen to stored in header
+                * "%s: Existing file has different snaplen %u, using it",
+                */
+               
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                               "%s: Existing file snaplen %u differs from 
supplied %u",
+                       fname, hdr.snaplen, p->snapshot);
+               return (1);
+       }
+
+       return (0);
+
+       error:
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: Corrupted log 
file.", fname);
+               return (1);
+}
+
 static pcap_dumper_t *
 pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
 {
-
+       struct stat st;
+       
 #if defined(WIN32) || defined(MSDOS)
        /*
         * If we're writing to the standard output, put it in binary
@@ -1197,13 +1275,30 @@
        else
                setbuf(f, NULL);
 #endif
-       if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
-               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
-                   fname, pcap_strerror(errno));
+       
+       if (fstat(fileno(f), &st) == -1) {
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't obtain status of 
%s: %s",
+                       fname, strerror(errno));
+               if (f != stdout)
+                       (void)fclose(f);
+               return (NULL);
+       }
+       
+       if (st.st_size == 0) {
+               if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
+                       snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to 
%s: %s",
+                       fname, pcap_strerror(errno));
+                       if (f != stdout)
+                               (void)fclose(f);
+                       return (NULL);
+               }
+       } else if (pcap_scan_dump(p, linktype, f, st.st_size, fname)) {
                if (f != stdout)
                        (void)fclose(f);
+               /* XXX move file and continue? */
                return (NULL);
        }
+       
        return ((pcap_dumper_t *)f);
 }
 
@@ -1229,9 +1324,9 @@
                fname = "standard output";
        } else {
 #if !defined(WIN32) && !defined(MSDOS)
-               f = fopen(fname, "w");
+               f = fopen(fname, "a+");
 #else
-               f = fopen(fname, "wb");
+               f = fopen(fname, "a+b");
 #endif
                if (f == NULL) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.

Reply via email to