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.