LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (https://www.linuxquestions.org/questions/linux-networking-3/)
-   -   Rotating capture files using tcpdump (https://www.linuxquestions.org/questions/linux-networking-3/rotating-capture-files-using-tcpdump-800385/)

prafulnama 04-06-2010 11:43 AM

Rotating capture files using tcpdump
 
Hello,

Ideally, I would like to set up tcpdump to rotate log file every 1 hour and retain files for the lat 14 days but I don't think any combination of -C and -W would allow me to do that (Atleast I haven't been able to figure it out), so I am trying to rotate the files every X number of MB and retain the last 20 files. This seems to be fairly simple with the '-C X -W 20' option but I am having some trouble in customizing the names of the log files. I have tried '-w capture-$(date +%Y-%M-%d-%H:%M-)' thinking that each file would start with the current date and time but all files are using the date and time when the capture was started so the only difference is the number at the end (which is done by -W). I would appreciate any help in figuring out if I can customize the names of the file so that it has the date and time when the capture in started. In fact if I can do that, I dont need the numbers that '-W' appends at the end but I dont know how to get rid of them.

Any if any experts can help me figure out how to do what I originally intended to (Rotate every hour and retain 14 days worth of files), I'll be more than happy :-)

Thanks everyone!
-p

rweaver 04-06-2010 12:55 PM

Internally in tcpdump I don't believe there is a way to achieve what you want. I'd tend towards writing a script that stopped the running tcpdump and started a new one every hour. Maybe something like this (as a base, needs refined and error checked, tested, etc.)
Code:

#!/bin/bash
killall -9 tcpdump
/usr/sbin/tcpdump -w /var/log/tcpdump/capture_$(date +%Y-%M-%d-%H:%M:%S).log

Then add that to cron to run hourly.

paulndna 08-13-2010 09:12 PM

try

tcpdump -w capture_%Y-%m-%d-%H:%M:%S

konsolebox 08-14-2010 12:08 AM

Try this script:
Code:

#!/bin/bash

shopt -s extglob

# variables

CURRENTDATE=''
DDBLOCKSIZE=512
LOGDIR='/var/log/tcpdump'
MAINLOGFILE='main.log'
MAINLOGFILEMAXSIZE=20000000  ## in bytes
OLD=14
QUIT=false
TCPDUMP='/usr/sbin/tcpdump'
TCPDUMPCAPTUREFILEPREFIX='capture-'
TCPDUMPCAPTUREFILESUFFIX=''
TCPDUMPPID=0
TEMPDIR='/var/tmp'

# functions

function log {
        echo "[$(date '+%F %T')] $1" >> "$MAINLOGFILE"
        echo "$1"
}

function checktcpdump {
        [[ $TCPDUMPPID -ne 0 ]] && [[ -e /proc/$TCPDUMPPID ]] && kill -s 0 "$TCPDUMPPID" 2>/dev/null
}

function starttcpdump {
        log "Starting tcpdump..."

        CURRENTDATE=$(date +%F)

        "$TCPDUMP" -w "$LOGDIR/${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}.log" &

        if [[ $? -ne 0 ]]; then
                TCPDUMPPID=0
                return 1
        fi

        TCPDUMPPID=$!

        disown "$TCPDUMPPID"

        checktcpdump
}

function starttcpdumploop {
        until starttcpdump; do
                log "Error: Failed to start tcpdump.  Waiting for 20 seconds before next attempt..."
                read -t 20 && QUIT=true
        done
}

function stoptcpdump {
        log "Stopping tcpdump..."
        kill "$TCPDUMPPID"
        checktcpdump && kill -s 9 "$TCPDUMPPID"
        TCPDUMPPID=0
        QUIT=true
}

function restarttcpdump {
        log "Restarting tcpdump..."
        checktcpdump && stoptcpdump
        starttcpdumploop
}

function catchsignals {
        log "Caught a signal..."
        QUIT=true
}

function main {
        local CAPTUREFILEPATTERN FILE MAINLOGFILEMAXBLOCKSIZE NEWDATE SIZE TEMPFILE

        CAPTUREFILEPATTERN="${TCPDUMPCAPTUREFILEPREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCPDUMPCAPTUREFILESUFFIX}.log"
        [[ $MAINLOGFILE != */* ]] && MAINLOGFILE=$LOGDIR/$MAINLOGFILE
        (( MAINLOGFILEMAXBLOCKSIZE = (MAINLOGFILEMAXSIZE / DDBLOCKSIZE) + ((MAINLOGFILEMAXSIZE % DDBLOCKSIZE) ? 0 : 1) ))

        log "Starting tcpdump manager script..."

        trap catchsignals SIGQUIT SIGINT SIGKILL SIGTERM

        mkdir -p "$LOGDIR"

        starttcpdumploop

        for (( I = 1;; I = (I + 1) % 20 )); do
                read -t 1 && break  ## we have to separate this from the next statement to ensure proper handling of signals

                [[ $QUIT = true ]] && break

                if [[ I -eq 0 ]]; then
                        NEWDATE=$(date +%F)

                        if [[ ! $NEWDATE = "$CURRENTDATE" ]]; then
                                log "A new day has come."

                                if read FILE; then
                                        log "Deleting $OLD-days old files..."

                                        while
                                                log "Deleting $FILE..."

                                                rm -f "$FILE"

                                                read FILE
                                        do
                                                continue
                                        done
                                fi < <(exec find "$LOGDIR" -name "$CAPTUREFILEPATTERN" -daystart -ctime "+$OLD")  # or -mtime?

                                restarttcpdump
                        fi
                elif [[ I -eq 1 ]]; then
                        SIZE=$(stat --printf=%s "$MAINLOGFILE")

                        if [[ $SIZE == +([[:digit:]]) && $(( SIZE / DDBLOCKSIZE )) -gt MAINLOGFILEMAXBLOCKSIZE ]]; then
                                echo "Reducing log data in $MAINLOGFILE..."

                                TEMPFILE=$TEMPDIR/tcpdump-$RANDOM.tmp

                                dd "bs=$DDBLOCKSIZE" "count=$MAINLOGFILEMAXBLOCKSIZE" "if=$MAINLOGFILE" "of=$TEMPFILE"

                                cat "$TEMPFILE" > "$MAINLOGFILE"; rm -f "$TEMPFILE"  ## better than mv
                        fi
                fi
        done

        checktcpdump && stoptcpdump

        log "Ending tcpdump manager script."
}

# start

main

I thought it was easy from the start but it took long. Please test it in a visible terminal before running in cron.

gagan_goku 05-12-2011 10:32 PM

use -G <num_seconds> -w 'trace_%Y%m%d-%H%M%S.pcap'

MED07 10-11-2012 10:50 AM

I think this is exactly what I’m looking for but I have a question about functionality.
 
Quote:

Originally Posted by konsolebox (Post 4065827)
Try this script:
Code:

#!/bin/bash

shopt -s extglob

# variables

CURRENTDATE=''
DDBLOCKSIZE=512
LOGDIR='/var/log/tcpdump'
MAINLOGFILE='main.log'
MAINLOGFILEMAXSIZE=20000000  ## in bytes
OLD=14
QUIT=false
TCPDUMP='/usr/sbin/tcpdump'
TCPDUMPCAPTUREFILEPREFIX='capture-'
TCPDUMPCAPTUREFILESUFFIX=''
TCPDUMPPID=0
TEMPDIR='/var/tmp'

# functions

function log {
        echo "[$(date '+%F %T')] $1" >> "$MAINLOGFILE"
        echo "$1"
}

function checktcpdump {
        [[ $TCPDUMPPID -ne 0 ]] && [[ -e /proc/$TCPDUMPPID ]] && kill -s 0 "$TCPDUMPPID" 2>/dev/null
}

function starttcpdump {
        log "Starting tcpdump..."

        CURRENTDATE=$(date +%F)

        "$TCPDUMP" -w "$LOGDIR/${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}.log" &

        if [[ $? -ne 0 ]]; then
                TCPDUMPPID=0
                return 1
        fi

        TCPDUMPPID=$!

        disown "$TCPDUMPPID"

        checktcpdump
}

function starttcpdumploop {
        until starttcpdump; do
                log "Error: Failed to start tcpdump.  Waiting for 20 seconds before next attempt..."
                read -t 20 && QUIT=true
        done
}

function stoptcpdump {
        log "Stopping tcpdump..."
        kill "$TCPDUMPPID"
        checktcpdump && kill -s 9 "$TCPDUMPPID"
        TCPDUMPPID=0
        QUIT=true
}

function restarttcpdump {
        log "Restarting tcpdump..."
        checktcpdump && stoptcpdump
        starttcpdumploop
}

function catchsignals {
        log "Caught a signal..."
        QUIT=true
}

function main {
        local CAPTUREFILEPATTERN FILE MAINLOGFILEMAXBLOCKSIZE NEWDATE SIZE TEMPFILE

        CAPTUREFILEPATTERN="${TCPDUMPCAPTUREFILEPREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCPDUMPCAPTUREFILESUFFIX}.log"
        [[ $MAINLOGFILE != */* ]] && MAINLOGFILE=$LOGDIR/$MAINLOGFILE
        (( MAINLOGFILEMAXBLOCKSIZE = (MAINLOGFILEMAXSIZE / DDBLOCKSIZE) + ((MAINLOGFILEMAXSIZE % DDBLOCKSIZE) ? 0 : 1) ))

        log "Starting tcpdump manager script..."

        trap catchsignals SIGQUIT SIGINT SIGKILL SIGTERM

        mkdir -p "$LOGDIR"

        starttcpdumploop

        for (( I = 1;; I = (I + 1) % 20 )); do
                read -t 1 && break  ## we have to separate this from the next statement to ensure proper handling of signals

                [[ $QUIT = true ]] && break

                if [[ I -eq 0 ]]; then
                        NEWDATE=$(date +%F)

                        if [[ ! $NEWDATE = "$CURRENTDATE" ]]; then
                                log "A new day has come."

                                if read FILE; then
                                        log "Deleting $OLD-days old files..."

                                        while
                                                log "Deleting $FILE..."

                                                rm -f "$FILE"

                                                read FILE
                                        do
                                                continue
                                        done
                                fi < <(exec find "$LOGDIR" -name "$CAPTUREFILEPATTERN" -daystart -ctime "+$OLD")  # or -mtime?

                                restarttcpdump
                        fi
                elif [[ I -eq 1 ]]; then
                        SIZE=$(stat --printf=%s "$MAINLOGFILE")

                        if [[ $SIZE == +([[:digit:]]) && $(( SIZE / DDBLOCKSIZE )) -gt MAINLOGFILEMAXBLOCKSIZE ]]; then
                                echo "Reducing log data in $MAINLOGFILE..."

                                TEMPFILE=$TEMPDIR/tcpdump-$RANDOM.tmp

                                dd "bs=$DDBLOCKSIZE" "count=$MAINLOGFILEMAXBLOCKSIZE" "if=$MAINLOGFILE" "of=$TEMPFILE"

                                cat "$TEMPFILE" > "$MAINLOGFILE"; rm -f "$TEMPFILE"  ## better than mv
                        fi
                fi
        done

        checktcpdump && stoptcpdump

        log "Ending tcpdump manager script."
}

# start

main

I thought it was easy from the start but it took long. Please test it in a visible terminal before running in cron.


It appears this script is a perfect fit for what I need... but I have a question.

Q: Does this rotate the "main.log" file or the tcpdump output?

I am looking for something that will rotate the output of the tcpdump file based on size. So when it reaches a max size the script will start a new tcpdump output with a new name (assuming more than one a day get created)... as in -- if 'x.pcap' exists then add a suffix like a,b,c...

* Also, it appears i'll need to add the specifics of the tcpdump arguments manually within the code
"$TCPDUMP" (manually add arguments here) -w "$LOGDIR/${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}.log" &

MED07 10-11-2012 11:23 AM

I added [TCPARGS="-npi eth1 -Xs 1500"] to the variables and inserted $TCPARGS after the TCPDUMP call:

"$TCPDUMP" $TCPARGS -w "$LOGDIR/${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}.log" &
and I get..
Starting tcpdump...
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 1500 bytes
so that seems to work as needed :)

* Any help in rotating the tcpdump output based on size would be great - thanks!

MED07 10-11-2012 03:16 PM

I have gone with a stripped down command/script for now:
tcpdump -npi eth1 -Xs 1500 -C 100 -w /tmp/dump.pcap

and a cron job:
* */1 * * * find /tmp/ -name "*.pcap*" -mmin +59 -exec rm {} \;

The problem of course is that I have to go stop the cron job and kill the pid for the tcpdump - when and if an event happens.

This is just a temporary measure in order to track an inconsistent problem... but if anyone has any better options that will give file rotation, log reporting and can be managed more easily than this one (as I have this running on all 4 of the boxes involved)... please do share - thanks!

konsolebox 10-11-2012 09:49 PM

Quote:

Originally Posted by MED07 (Post 4803118)
It appears this script is a perfect fit for what I need... but I have a question.

Q: Does this rotate the "main.log" file or the tcpdump output?

The tcpdump output is rotated on a per-day basis while the main.log file is not rotated but truncated to its limit size every time it reaches it. Checking is done every 20 seconds. I think there's still a better way to do it though, like a custom time interval for when the checking would be done. The script would have to be revised for that.
Quote:

I am looking for something that will rotate the output of the tcpdump file based on size. So when it reaches a max size the script will start a new tcpdump output with a new name (assuming more than one a day get created)... as in -- if 'x.pcap' exists then add a suffix like a,b,c...
Well I'll see if we could make things work that way.
Quote:

* Also, it appears i'll need to add the specifics of the tcpdump arguments manually within the code
"$TCPDUMP" (manually add arguments here) -w "$LOGDIR/${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}.log" &
Using arrays for passing arguments is the safest way as IFS does not affect it.
Code:

TCPDUMPARGS=("arg with space 1" "arg 2" "...")
tcpdump "${TCPDUMPARGS[@]}" ...


konsolebox 10-12-2012 01:16 AM

I updated the script. This time a new filename for the logfile is used every time a new session is started. Note that tcpdump doesn't seem to allow appending of output to a logfile from previous session.

Code:

#!/bin/bash

shopt -s extglob

# variables

CURRENTDATE=''
DDBLOCKSIZE=512
LOGDIR='/var/log/tcpdump'
MAINLOGFILE='main.log'
MAINLOGFILEMAXSIZE=20000000  ## in bytes
OLD=14
QUIT=false
TCPDUMP='/usr/sbin/tcpdump'
TCPDUMPARGS=(-C 1)  ## customize arguments here e.g. (-C 1 "another with spaces")
TCPDUMPCAPTUREFILEPREFIX='capture-'
TCPDUMPCAPTUREFILESUFFIX=''
TCPDUMPPID=0
TEMPDIR='/var/tmp'

# functions

function log {
        echo "[$(date '+%F %T')] $1" >> "$MAINLOGFILE"
        echo "$1"
}

function checktcpdump {
        [[ $TCPDUMPPID -ne 0 ]] && [[ -e /proc/$TCPDUMPPID ]] && kill -s 0 "$TCPDUMPPID" 2>/dev/null
}

function starttcpdump {
        log "Starting tcpdump..."

        CURRENTDATE=$(date +%F)

        BASENAME="${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}"

        readarray -t EXISTINGFILES < <(compgen -G "$LOGDIR/${BASENAME}.+([[:digit:]]).log*([[:digit:]])")

        NEXT_SESSION=0

        if [[ ${#EXISTINGFILES[@]} -gt 0 ]]; then
                for FILE in "${EXISTINGFILES[@]}"; do
                        SESSION_NUMBER=${FILE%.log*}
                        SESSION_NUMBER=${SESSION_NUMBER##*.}
                        [[ $SESSION_NUMBER == +([[:digit:]]) && SESSION_NUMBER -ge NEXT_SESSION ]] && NEXT_SESSION=$(( SESSION_NUMBER + 1 ))
                done
        fi

        OUTPUTFILE=$LOGDIR/${BASENAME}.$NEXT_SESSION.log

        "$TCPDUMP" "${TCPDUMPARGS[@]}" -w "$OUTPUTFILE" &

        if [[ $? -ne 0 ]]; then
                TCPDUMPPID=0
                return 1
        fi

        TCPDUMPPID=$!

        disown "$TCPDUMPPID"

        checktcpdump
}

function starttcpdumploop {
        until starttcpdump; do
                log "Error: Failed to start tcpdump.  Waiting for 20 seconds before next attempt..."
                read -t 20
                [[ $QUIT = true ]] && {
                        log "Ending tcpdump manager script."
                        exit
                }
        done
}

function stoptcpdump {
        log "Stopping tcpdump..."
        kill "$TCPDUMPPID"
        checktcpdump && kill -s 9 "$TCPDUMPPID"
        TCPDUMPPID=0
        QUIT=true
}

function restarttcpdump {
        log "Restarting tcpdump..."
        checktcpdump && stoptcpdump
        starttcpdumploop
}

function catchsignals {
        log "Caught a signal..."
        QUIT=true
}

function main {
        local CAPTUREFILEPATTERN FILE MAINLOGFILEMAXBLOCKSIZE NEWDATE SIZE TEMPFILE

        CAPTUREFILEPATTERN="${TCPDUMPCAPTUREFILEPREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCPDUMPCAPTUREFILESUFFIX}.log*"
        [[ $MAINLOGFILE != */* ]] && MAINLOGFILE=$LOGDIR/$MAINLOGFILE
        (( MAINLOGFILEMAXBLOCKSIZE = (MAINLOGFILEMAXSIZE / DDBLOCKSIZE) + ((MAINLOGFILEMAXSIZE % DDBLOCKSIZE) ? 0 : 1) ))

        log "Starting tcpdump manager script..."

        trap catchsignals SIGQUIT SIGINT SIGKILL SIGTERM

        mkdir -p "$LOGDIR"

        starttcpdumploop

        for (( I = 1;; I = (I + 1) % 20 )); do
                read -t 1  ## we have to separate this from the next statement to ensure proper handling of signals

                [[ $QUIT = true ]] && break

                if [[ I -eq 0 ]]; then
                        NEWDATE=$(date +%F)

                        if [[ ! $NEWDATE = "$CURRENTDATE" ]]; then
                                log "A new day has come."

                                if read FILE; then
                                        log "Deleting $OLD-days old files..."

                                        while
                                                log "Deleting $FILE..."

                                                rm -f "$FILE"

                                                read FILE
                                        do
                                                continue
                                        done
                                fi < <(exec find "$LOGDIR" -name "$CAPTUREFILEPATTERN" -daystart -ctime "+$OLD")  # or -mtime?

                                restarttcpdump
                        fi
                elif [[ I -eq 1 ]]; then
                        SIZE=$(stat --printf=%s "$MAINLOGFILE")

                        if [[ $SIZE == +([[:digit:]]) && $(( SIZE / DDBLOCKSIZE )) -gt MAINLOGFILEMAXBLOCKSIZE ]]; then
                                echo "Reducing log data in $MAINLOGFILE..."

                                TEMPFILE=$TEMPDIR/tcpdump-$RANDOM.tmp

                                dd "bs=$DDBLOCKSIZE" "count=$MAINLOGFILEMAXBLOCKSIZE" "if=$MAINLOGFILE" "of=$TEMPFILE"

                                cat "$TEMPFILE" > "$MAINLOGFILE"; rm -f "$TEMPFILE"  ## better than mv
                        fi
                fi
        done

        checktcpdump && stoptcpdump

        log "Ending tcpdump manager script."
}

# start

main

Btw you need bash > 4.0 or else readarray won't work but if you need to use bash 3.0+ just tell me.

For rotation of logfiles based from size you need to use -C of tcpdump. Also, make sure LOGDIR is writeable both by running user and tcpdump (user) - if tcpdump runs with its own user. You can do this by setting 777 to directory, setting 770 with tcpdump, or anything applicable as group, or changing its ownership to tcpdump or tcpdump:tcpdump.

MED07 10-12-2012 10:52 AM

Thanks Konsolebox -
I have bash version 3.2.25(1)
Will the readarray problem show up when starting/restaring the script? It created today's file with a '.0.log' but when I restart the script it overwrites it.
> Oct 11 11:16 capture-2012-10-11.log
> Oct 12 10:47 capture-2012-10-12.0.log

konsolebox 10-12-2012 07:46 PM

Quote:

Originally Posted by MED07 (Post 4804016)
Thanks Konsolebox -
I have bash version 3.2.25(1)
Will the readarray problem show up when starting/restaring the script? It created today's file with a '.0.log' but when I restart the script it overwrites it.
> Oct 11 11:16 capture-2012-10-11.log
> Oct 12 10:47 capture-2012-10-12.0.log

The script would overwrite it since readarray doesn't work with bash-3.2.

I have now modified the script. I tested this with bash 3.2 as well. Please try it again.
Code:

#!/bin/bash

shopt -s extglob

# variables

CURRENTDATE=''
DDBLOCKSIZE=512
LOGDIR='/var/log/tcpdump'
MAINLOGFILE='main.log'
MAINLOGFILEMAXSIZE=20000000  ## in bytes
OLD=14
QUIT=false
TCPDUMP='/usr/sbin/tcpdump'
TCPDUMPARGS=(-C 1)  ## customize arguments here e.g. (-C 1 "another with spaces")
TCPDUMPCAPTUREFILEPREFIX='capture-'
TCPDUMPCAPTUREFILESUFFIX=''
TCPDUMPPID=0
TEMPDIR='/var/tmp'

# functions

function log {
        echo "[$(date '+%F %T')] $1" >> "$MAINLOGFILE"
        echo "$1"
}

function checktcpdump {
        [[ $TCPDUMPPID -ne 0 ]] && [[ -e /proc/$TCPDUMPPID ]] && kill -s 0 "$TCPDUMPPID" 2>/dev/null
}

function starttcpdump {
        log "Starting tcpdump..."

        CURRENTDATE=$(date +%F)

        BASENAME="${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}"

        {
                if [[ BASH_VERSINFO -ge 4 ]]; then
                        readarray -t EXISTINGFILES
                else
                        EXISTINGFILES=()
                        EXISTINGFILES_COUNT=0
                        while read LINE; do
                                EXISTINGFILES[EXISTINGFILES_COUNT++]=$LINE
                        done
                fi
        } < <(compgen -G "$LOGDIR/${BASENAME}.+([[:digit:]]).log*([[:digit:]])")

        NEXT_SESSION=0

        if [[ ${#EXISTINGFILES[@]} -gt 0 ]]; then
                for FILE in "${EXISTINGFILES[@]}"; do
                        SESSION_NUMBER=${FILE%.log*}
                        SESSION_NUMBER=${SESSION_NUMBER##*.}
                        [[ $SESSION_NUMBER == +([[:digit:]]) && SESSION_NUMBER -ge NEXT_SESSION ]] && NEXT_SESSION=$(( SESSION_NUMBER + 1 ))
                done
        fi

        OUTPUTFILE=$LOGDIR/${BASENAME}.$NEXT_SESSION.log

        "$TCPDUMP" "${TCPDUMPARGS[@]}" -w "$OUTPUTFILE" &

        if [[ $? -ne 0 ]]; then
                TCPDUMPPID=0
                return 1
        fi

        TCPDUMPPID=$!

        disown "$TCPDUMPPID"

        checktcpdump
}

function starttcpdumploop {
        until starttcpdump; do
                log "Error: Failed to start tcpdump.  Waiting for 20 seconds before next attempt..."
                read -t 20
                [[ $QUIT = true ]] && {
                        log "Ending tcpdump manager script."
                        exit
                }
        done
}

function stoptcpdump {
        log "Stopping tcpdump..."
        kill "$TCPDUMPPID"
        checktcpdump && kill -s 9 "$TCPDUMPPID"
        TCPDUMPPID=0
        QUIT=true
}

function restarttcpdump {
        log "Restarting tcpdump..."
        checktcpdump && stoptcpdump
        starttcpdumploop
}

function catchsignals {
        log "Caught a signal."
        QUIT=true
}

function main {
        local CAPTUREFILEPATTERN FILE NEWDATE SIZE SKIP TEMPFILE

        CAPTUREFILEPATTERN="${TCPDUMPCAPTUREFILEPREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCPDUMPCAPTUREFILESUFFIX}.log*"
        [[ $MAINLOGFILE != */* ]] && MAINLOGFILE=$LOGDIR/$MAINLOGFILE

        log "Starting tcpdump manager script..."

        trap catchsignals SIGQUIT SIGINT SIGKILL SIGTERM

        mkdir -p "$LOGDIR"

        starttcpdumploop

        for (( I = 1;; I = (I + 1) % 20 )); do
                read -t 1  ## we have to separate this from the next statement to ensure proper handling of signals

                [[ $QUIT = true ]] && break

                if [[ I -eq 0 ]]; then
                        NEWDATE=$(exec date +%F)

                        if [[ ! $NEWDATE = "$CURRENTDATE" ]]; then
                                log "A new day has come."

                                if read FILE; then
                                        log "Deleting $OLD-days old files..."

                                        while
                                                log "Deleting $FILE..."

                                                rm -f "$FILE"

                                                read FILE
                                        do
                                                continue
                                        done
                                fi < <(exec find "$LOGDIR" -name "$CAPTUREFILEPATTERN" -daystart -ctime "+$OLD")  # or -mtime?

                                restarttcpdump
                        fi
                elif [[ I -eq 1 ]]; then
                        SIZE=$(exec stat --printf=%s "$MAINLOGFILE")

                        if [[ $SIZE == +([[:digit:]]) && SIZE -gt MAINLOGFILEMAXSIZE ]]; then
                                log "Reducing log data in $MAINLOGFILE..."

                                TEMPFILE=$TEMPDIR/tcpdump-$RANDOM.tmp
                                SKIP=$(( (SIZE - MAINLOGFILEMAXSIZE) / DDBLOCKSIZE ))

                                dd "bs=$DDBLOCKSIZE" "skip=$SKIP" "if=$MAINLOGFILE" "of=$TEMPFILE"
                                cat "$TEMPFILE" > "$MAINLOGFILE"; rm -f "$TEMPFILE"  ## better than mv
                        fi
                fi
        done

        checktcpdump && stoptcpdump

        log "Ending tcpdump manager script."
}

# start

main


konsolebox 10-12-2012 09:09 PM

And this is yet another version for it. This one's more flexible and lighter performance-wise.
Code:

#!/bin/bash

shopt -s extglob

# settings

LOGDIR='/var/log/tcpdump'

MAINLOGFILE='main.log'
MAINLOGFILEMAXSIZE=$(( 20 * 1024 * 1024 ))  ## in bytes. File is reduced when this size is reached.
MAINLOGFILEALLOWANCE=$(( 1 * 1024 * 1024 ))  ## in bytes. This is the extra space given when file is reduced.
MAINLOGCHECKINTERVALS=300 ## seconds. Recommended: >= 300

TCPDUMP='/usr/sbin/tcpdump'
TCPDUMPARGS=(-C 1) ## customize arguments here e.g. (-C 1 "another with spaces")
TCPDUMPCAPTUREFILEPREFIX='capture-'
TCPDUMPCAPTUREFILESUFFIX=''
TCPDUMPCHECKINTERVALS=60 ## seconds

OLD=14  ## days

DDBLOCKSIZE=512  ## bytes

TEMPDIR='/var/tmp'

# other variables

CURRENTDATE=''
QUIT=false
TCPDUMPPID=0

# functions

function log {
        echo "[$(date '+%F %T')] $1" >> "$MAINLOGFILE"
        echo "$1"
}

function checktcpdump {
        [[ $TCPDUMPPID -ne 0 ]] && [[ -e /proc/$TCPDUMPPID ]] && kill -s 0 "$TCPDUMPPID" 2>/dev/null
}

function starttcpdump {
        log "Starting tcpdump..."

        local CURRENTDATE=CURRENTDATE=$(date +%F)
        local BASENAME="${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}"
        local -a EXISTINGFILES
       
        {
                if [[ BASH_VERSINFO -ge 4 ]]; then
                        readarray -t EXISTINGFILES
                else
                        EXISTINGFILES=()
                        local -i I=0
                        while read LINE; do
                                EXISTINGFILES[I++]=$LINE
                        done
                fi
        } < <(compgen -G "$LOGDIR/${BASENAME}.+([[:digit:]]).log*([[:digit:]])")

        local NEXT_SESSION=0

        if [[ ${#EXISTINGFILES[@]} -gt 0 ]]; then
                local SESSION_NUMBER
                for FILE in "${EXISTINGFILES[@]}"; do
                        SESSION_NUMBER=${FILE%.log*}
                        SESSION_NUMBER=${SESSION_NUMBER##*.}
                        [[ $SESSION_NUMBER == +([[:digit:]]) && SESSION_NUMBER -ge NEXT_SESSION ]] && NEXT_SESSION=$(( SESSION_NUMBER + 1 ))
                done
        fi

        local OUTPUTFILE=$LOGDIR/${BASENAME}.$NEXT_SESSION.log

        "$TCPDUMP" "${TCPDUMPARGS[@]}" -w "$OUTPUTFILE" &

        if [[ $? -ne 0 ]]; then
                TCPDUMPPID=0
                return 1
        fi

        TCPDUMPPID=$!

        disown "$TCPDUMPPID"

        checktcpdump
}

function starttcpdumploop {
        until starttcpdump; do
                log "Error: Failed to start tcpdump.  Waiting for 20 seconds before next attempt..."
                read -t 20
                [[ $QUIT = true ]] && {
                        log "Ending tcpdump manager script."
                        exit
                }
        done
}

function stoptcpdump {
        log "Stopping tcpdump..."
        kill "$TCPDUMPPID"
        checktcpdump && kill -s 9 "$TCPDUMPPID"
        TCPDUMPPID=0
        QUIT=true
}

function restarttcpdump {
        log "Restarting tcpdump..."
        checktcpdump && stoptcpdump
        starttcpdumploop
}

function catchsignals {
        log "Caught a signal."
        QUIT=true
}

function main {
        local CAPTUREFILEPATTERN FILE NEWDATE SIZE TEMPFILE
        local -i I

        CAPTUREFILEPATTERN="${TCPDUMPCAPTUREFILEPREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCPDUMPCAPTUREFILESUFFIX}.log*"
        [[ $MAINLOGFILE != */* ]] && MAINLOGFILE=$LOGDIR/$MAINLOGFILE

        log "Starting tcpdump manager script..."

        [[ $MAINLOGFILEMAXSIZE == +([[:digit:]]) && MAINLOGFILEMAXSIZE -gt DDBLOCKSIZE ]] || {
                echo "MAINLOGFILEMAXSIZE is not valid."
                return 1
        }
        [[ $MAINLOGFILEALLOWANCE == +([[:digit:]]) && MAINLOGFILEALLOWANCE -gt DDBLOCKSIZE && MAINLOGFILEALLOWANCE -lt MAINLOGFILEMAXSIZE ]] || {
                echo "MAINLOGFILEALLOWANCE is not valid."
                return 1
        }

        trap catchsignals SIGQUIT SIGINT SIGKILL SIGTERM

        mkdir -p "$LOGDIR"

        starttcpdumploop

        for (( I = 1;; I = (I + 1) % 10000 )); do
                read -t 1  ## we have to separate this from the next statement to ensure proper handling of signals

                [[ $QUIT = true ]] && break

                if (( (I % TCPDUMPCHECKINTERVALS) == 0 )); then
                        NEWDATE=$(exec date +%F)

                        if [[ ! $NEWDATE = "$CURRENTDATE" ]]; then
                                log "A new day has come."

                                if read FILE; then
                                        log "Deleting $OLD-days old files..."

                                        while
                                                log "Deleting $FILE..."

                                                rm -f "$FILE"

                                                read FILE
                                        do
                                                continue
                                        done
                                fi < <(exec find "$LOGDIR" -name "$CAPTUREFILEPATTERN" -daystart -ctime "+$OLD")  # or -mtime?

                                restarttcpdump
                        fi
                fi
                if (( (I % MAINLOGCHECKINTERVALS) == 0 )); then
                        SIZE=$(exec stat --printf=%s "$MAINLOGFILE")

                        if [[ $SIZE == +([[:digit:]]) && SIZE -gt MAINLOGFILEMAXSIZE ]]; then
                                log "Reducing log data in $MAINLOGFILE..."

                                TEMPFILE=$TEMPDIR/tcpdump-$RANDOM.tmp
                                SKIP=$(( (SIZE - (MAINLOGFILEMAXSIZE - MAINLOGFILEALLOWANCE)) / DDBLOCKSIZE ))

                                dd "bs=$DDBLOCKSIZE" "skip=$SKIP" "if=$MAINLOGFILE" "of=$TEMPFILE"
                                cat "$TEMPFILE" > "$MAINLOGFILE"; rm -f "$TEMPFILE"  ## better than mv
                        fi
                fi
        done

        checktcpdump && stoptcpdump

        log "Ending tcpdump manager script."
}

# start

main


MED07 10-13-2012 11:23 AM

you're awesome! - that did it:
- capture-2012-10-13.0.log (capture started)
- capture-2012-10-13.0.log1 (capture rolled over based on file size)
- capture-2012-10-13.1.log (capture stopped and restarted)
- capture-2012-10-13.2.log (capture stopped and restarted)
- main.log

I think I'll use a cron job to start this script '@reboot' if that works... and will continue to use a cron job to clean off logs older than x number of hours.

Thanks so much for your help!!

konsolebox 10-14-2012 01:49 AM

Welcome :)

mbrauni 07-01-2014 05:50 PM

Hi,

today I found your nice script and tried to use it on my machine, but it does not work for me and I don't understand why. When I run the script, tcpdump gets started, but after about a minute, it get stopped by the script. This is the output from the main.log file:

Code:

[2014-07-02 00:47:08] Starting tcpdump manager script...
[2014-07-02 00:47:08] Starting tcpdump...
[2014-07-02 00:47:08] Output File: /home/backup/tcpdump/capture-2014-07-02.0.log
[2014-07-02 00:48:08] A new day has come.
[2014-07-02 00:48:08] Restarting tcpdump...
[2014-07-02 00:48:08] Stopping tcpdump...
[2014-07-02 00:48:08] Starting tcpdump...
[2014-07-02 00:48:08] Output File: /home/backup/tcpdump/capture-2014-07-02.1.log
[2014-07-02 00:48:09] Stopping tcpdump...
[2014-07-02 00:48:09] Ending tcpdump manager script.

In my log directory I just have the capture-2014-07-02.0.log file.

Can you please help me with this issue?

konsolebox 07-02-2014 02:05 PM

@mbrauni Hi. On what system do you use this? It could be a tcpdump problem or perhaps something related to date command especially if you're on mac. find may act differently as well.

P.S. I just found out: The newer version has a typo:
Code:

CURRENTDATE=CURRENTDATE=...

anandpu70 08-23-2014 02:13 AM

And this is yet another version for it. This one's more flexible and lighter performance-wise.
 
Hi Consolebox,

I have gone through your script and it has written some time back. I have requirement of running tcpdump 24 hours captured into the same file for 24 hours packets. Next days packets it has to be captured in nex date's file. Acutally its working but problem is tcpdump is for some reason stopping after 2 hours. Do you know why. If you could help it will be great help.

I am running following version Linux.

Linux 2.6.18-274.el5 #1 SMP Fri Jul 8 17:36:59 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux

[bash-3.2-32.el5]


Thanks,
Anand.

keith.evans 06-12-2015 12:52 PM

Run for 60 seconds and quit?
 
First off konsolebox, this script is really great. Thank you.

I've learned a bunch just from working with and getting to understand it. I had an issue with temporary blindness finding clearly stated variables... Found what was needed just after posting (TCPDUMPCHECKINTERVALS=180).

konsolebox 06-13-2015 12:00 AM

@mbrauni, @anandpu70, @keith.evans

I reformatted the code to make it more readable. I also found some issues:

(1) CURRENT_DATE should have been not set as a local variable. What happens is the date value set to it is lost after start_tcpdump() exits which makes [[ ${NEW_DATE} != "${CURRENT_DATE}" ]] always valid.

(2) stop_tcpdump() should have not been setting QUIT to true. It makes the script end quickly when stop_tcpdump() or restart_tcpdump() is called.

I now have the script placed in Github. Please check it for all updates.

https://github.com/konsolebox/script...dump-master.sh

keith.evans 06-18-2015 01:24 PM

Great newer version, thanks and some updates/enhancements
 
Thank you again konsolebox for this excellent script. I had some requirements that I needed to satisfy since I don't have root on production and not managing that environment wanted to ensure I didn't blow it up as I can't monitor the progress and the systems are very high traffic. Below I list the changes/updates made and provide the updated code (using your newest version).

Primary additions: updated logging for no-out when cron, min and max number capture files max disk space for capture file, added make dir function for non-root access to capture files after, capture file extension configurable, and prompt for pre-set protos with default selection.


Code:

#!/bin/bash
# ----------------------------------------------------------------------

# tcpdump-master
#
# The script is a tcpdump service starter and manager.  It can also
# automatically delete files older than C days, and reduce the size of
# the main log file if it's already larger than N bytes.
#
# The script was originally a solution for this thread in LQ:
# https://www.linuxquestions.org/questions/linux-networking-3/rotating-capture-files-using-tcpdump-800385/
#
# Note: It is recommended to use Bash version 4.3 or newer to prevent
# crashes related to race conditions in catching signals and handling
# traps.
#
# Disclaimer: This tool comes with no warranty.
#
# Author: konsolebox
# Copyright Free / Public Domain
# June 13, 2015
#
# Modification Log
#    date      ver    author            description
# ---------- ------- ----------- --------------------------------------
# 06/15/2015  v.0.2 kevans      Addded updated logging for no-out when
#                                cron, min and max number capture files
#                                max disk space for capture file, added
#                                make dir function for non-root access
#                                to capture files after, capture file
#                                extension, and prompt for proto with
#                                default proto selection.
# ----------------------------------------------------------------------

if [ -z "${BASH_VERSION}" ]; then
        echo "You need Bash to run this script."
        exit 1
fi

shopt -s extglob

# Settings

LOG_DIR='/var/log/tcpdump'
NOTROOT_DEFAULT_GROUP="users"
case "$-" in
*i*) INTERACTIVE=0 ;;
*) INTERACTIVE=-1 ;;
esac

MAIN_LOG_FILE='main.log'
MAIN_LOG_FILE_MAX_SIZE=$(( 20 * 1024 * 1024 ))  ## in bytes. File is reduced when this size is reached.
MAIN_LOG_FILE_ALLOWANCE=$(( 1 * 1024 * 1024 ))  ## in bytes. This is the extra space given when file is reduced.
MAIN_LOG_CHECK_INTERVALS=300 ## seconds. Recommended: >= 300

TCP_DUMP='/usr/sbin/tcpdump'
HELP_MESSAGE="Usage: `basename $0` options (-p|-proto [ssh|http|ftp|all]) -h for help"
TCPDUMP_PROTO="(tcp port 444 or tcp port 443)" # default
while getopts ":p:proto:h" opt; do
  case ${opt} in
    p|proto)
      case `echo ${OPTARG} | tr '[:upper:]' '[:lower:]'` in
        ssh|scp)
          TCPDUMP_PROTO="(tcp port 22)"
          ;;
        http|https|ssl)
          TCPDUMP_PROTO="(tcp port 444 or tcp port 443)"
          ;;
        ftp|ftps)
          TCPDUMP_PROTO="(tcp port 21)"
          ;;
        h|help)
          if [ $INTERACTIVE ]; then log $HELP_MESSAGE; fi
          ;;
        all|*)
          TCPDUMP_PROTO="(tcp port 444 or tcp port 443 or tcp port 21 or tcp port 22)"
          ;;
      esac
      ;;
  h|H|help|HELP)
      if [ $INTERACTIVE ]; then log $HELP_MESSAGE; fi
      ;;
  esac
done
echo $TCPDUMP_PROTO
TCP_DUMPARGS="(-C 1 -ieth0 -s168 -Z $USER '${TCPDUMP_PROTO}')" ## customize arguments here e.g. (-C 1 "another with spaces")
TCP_DUMP_CAPTURE_FILE_PREFIX='capture-'
TCP_DUMP_CAPTURE_FILE_SUFFIX=''
TCP_DUMP_CAPTURE_FILE_EXT='.log'
TCP_DUMP_CAPTURE_FILES_MIN=20
TCP_DUMP_CAPTURE_FILES_MAX=100
TCP_DUMP_CAPTURE_FILE_MAX_STORAGE=1048576 # bytes (1 MB: 1048576, 1 GB: 1073741824)
TCP_DUMP_CHECK_INTERVALS=180 ## seconds run time before kill (1 day: 86400, 1 hour: 3600)

OLD=14  ## days
DD_BLOCKSIZE=512  ## bytes
TEMP_DIR='/var/tmp'

# other runtime variables

CURRENT_DATE=''
TCPDUMP_PID=0
QUIT=false

# functions

function makedir {
        # make sure we have access after logs and captures created
        mkdir -p $1
        if [[ ${EUID} -ne 0 ]]; then
                chgrp ${NOTROOT_DEFAULT_GROUP} ${1}
                chmod 777 ${1}
                chmod g+s ${1}
        fi
}

function log {
        echo "[$(date '+F %T')] $1" >> "${MAIN_LOG_FILE}"
        if [ ${INTERACTIVE} ]; then echo "$1"; fi
}

function check_tcpdump {
        [[ ${TCPDUMP_PID} -ne 0 ]] && [[ -e /proc/${TCPDUMP_PID} ]] && kill -s 0 "${TCPDUMP_PID}" 2>/dev/null
}

function start_tcpdump {
        log "Starting tcpdump."

        CURRENT_DATE=$(date +%F)
        local BASENAME="${TCP_DUMP_CAPTURE_FILE_PREFIX}${CURRENT_DATE}${TCP_DUMP_CAPTURE_FILE_SUFFIX}"
        local EXISTING_FILES=()

        {
                if [[ BASH_VERSINFO -ge 4 ]]; then
                        readarray -t EXISTING_FILES
                else
                        local -i I=0
                        while read LINE; do
                                EXISTING_FILES[I++]=${}LINE}
                        done
                fi
        } < <(compgen -G "${LOG_DIR}/${BASENAME}.+([[:digit:]])${TCP_DUMP_CAPTURE_FILE_EXT}*([[:digit:]])")

        local NEXT_SESSION=0

        if [[ ${#EXISTING_FILES[@]} -gt 0 ]]; then
                local SESSION_NUMBER
                for FILE in "${EXISTING_FILES[@]}"; do
                        SESSION_NUMBER=${FILE%${TCP_DUMP_CAPTURE_FILE_EXT}*}
                        SESSION_NUMBER=${SESSION_NUMBER##*.}
                        [[ ${SESSION_NUMBER} == +([[:digit:]]) && SESSION_NUMBER -ge NEXT_SESSION ]] && NEXT_SESSION=$(( SESSION_NUMBER + 1 ))
                done
        fi

        local OUTPUT_FILE=${LOG_DIR}/${BASENAME}.${NEXT_SESSION}${TCP_DUMP_CAPTURE_FILE_EXT}

        log "Will run with these args: ${TCP_DUMP} ${TCPDUMP_ARGS[@]} -w ${OUTPUT_FILE}"
        if [[ "$(id -u)" != "0" && ${INTERACTIVE} ]]; then
                sudo "${TCP_DUMP}" "${TCPDUMP_ARGS}" -w "${OUTPUT_FILE}" &
        else
                "${TCP_DUMP}" "${TCPDUMP_ARGS}" -w "${OUTPUT_FILE}" &
        fi

        if [[ $? -ne 0 ]]; then
                TCPDUMP_PID=0
                return 1
        fi

        TCPDUMP_PID=$!
        disown "${TCPDUMP_PID}"
        log "PID of tcpdump: ${TCPDUMP_PID}"
        check_tcpdump
}

function start_tcpdump_loop {
        until start_tcpdump; do
                log "Error: Failed to start tcpdump.  Waiting for 20 seconds before next attempt."
                read -t 20

                if [[ ${QUIT} == true ]]; then
                        log "Ending tcpdump manager script."
                        exit
                fi
        done
}

function stop_tcpdump {
        log "Stopping tcpdump."
        kill "${TCPDUMP_PID}"
        sleep 1
        check_tcpdump && kill -s 9 "${TCPDUMP_PID}"
        TCPDUMP_PID=0
}

function restart_tcpdump {
        log "Restarting tcpdump."
        check_tcpdump && stop_tcpdump
        start_tcpdump_loop
}

function signal_caught_callback {
        local SIGNAL=$1
        log "Caught signal ${SIGNAL}."
        QUIT=true
}

function main {
        local CAPTURE_FILE_PATTERN FILE NEW_DATE SIZE TEMP_FILE I

        CAPTURE_FILE_PATTERN="${TCP_DUMP_CAPTURE_FILE_PREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCP_DUMP_CAPTURE_FILE_SUFFIX}${TCP_DUMP_CAPTURE_FILE_EXT}*"
        [[ ${MAIN_LOG_FILE} != */* ]] && MAINLOGFILE=${LOG_DIR}/${MAINLOGFILE}

        makedir ${LOG_DIR}
        pushd ${LOG_DIR}

        log "----------------------------------------"
        log "Starting up."
        log "PID: $$"

        [[ ${MAIN_LOG_FILE_MAX_SIZE} == +([[:digit:]]) && MAIN_LOG_FILE_MAX_SIZE -gt DD_BLOCK_SIZE ]] || {
                echo "MAIN_LOG_FILE_MAX_SIZE is not valid: ${MAIN_LOG_FILE_MAX_SIZE}"
                return 1
        }

        [[ ${MAIN_LOG_FILE_ALLOWANCE} == +([[:digit:]]) && MAIN_LOG_FILE_ALLOWANCE -gt DD_BLOCK_SIZE && MAIN_LOG_FILE_ALLOWANCE -lt MAIN_LOG_FILE_MAX_SIZE ]] || {
                echo "MAIN_LOG_FILE_ALLOWANCE is not valid: ${MAIN_LOG_FILE_ALLOWANCE}"
                return 1
        }

        for S in SIGQUIT SIGINT SIGKILL SIGTERM; do
                eval "
                        function catch_${S} { signal_caught_callback ${S}; }
                        trap catch_${S} ${S}
                "
        done

        start_tcpdump_loop

        for (( I = 1;; I = (I + 1) % 10000 )); do
                read -t 1  ## we have to separate this from the next statement to ensure proper handling of signals

                [[ ${QUIT} = true ]] && break

                if (( (I % TCP_DUMP_CHECK_INTERVALS) == 0 )); then
                        NEW_DATE=$(exec date +%F)

                        if [[ ! ${NEW_DATE} = "${CURRENT_DATE}" ]]; then
                                log "A new day has come."

                                # cleanup based on packet capture age
                                if read FILE; then
                                        log "Deleting ${OLD}-days old files."

                                        while
                                                log "Deleting ${FILE}."
                                                rm -f "${FILE}"
                                                read FILE
                                        do
                                                continue
                                        done
                                fi < <(exec find "${LOG_DIR}" -name "${CAPTURE_FILE_PATTERN}" -daystart -ctime "+${OLD}")  # or -mtime?

                                # cleanup based on packet capture max size and min count
                                while [[ `du -bc ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | tail -1 | cut -f1` -gt ${TCP_DUMP_CAPTURE_FILE_MAX_STORAGE} ]]
                                do
                                                                        if [[ `ls -1 ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | wc -l` -gt ${TCP_DUMP_CAPTURE_FILES_MIN} ]]; then
                                                                                log "Deleting files exceeding max storage (${TCP_DUMP_CAPTURE_FILE_MAX_STORAGE} bytes) and min count (${TCP_DUMP_CAPTURE_FILES_MIN})..."
                                                                                log " - Current storage used: `du -bc ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | tail -1` bytes"
                                                                                CNT=`ls -1 ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | wc -l`
                                                                                log " - Current file count: ${CNT}"
                                                                                                                        FILE=`ls -t ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | tail -1`
                                                                                                                        log " - Deleting ${FILE}..."
                                                                                                                        rm -f ${FILE}
                                                                        fi
                                done

                                while [[ `ls -1 ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | wc -l` -gt ${TCP_DUMP_CAPTURE_FILES_MAX} ]]
                                do
                                        log "Deleting files exceeding max allowed (${TCP_DUMP_CAPTURE_FILES_MAX})..."
                                        FILE=`ls -t ${LOG_DIR}/${TCP_DUMP_CAPTURE_FILE_PREFIX}* | tail -1`
                                        log "Deleting ${FILE}..."
                                        rm -f ${FILE}
                                done

                                restart_tcpdump
                        fi
                fi

                if (( (I % MAIN_LOG_CHECK_INTERVALS) == 0 )); then
                        SIZE=$(stat --printf=%s "${MAIN_LOG_FILE}")

                        if [[ ${SIZE} == +([[:digit:]]) && SIZE -gt MAIN_LOG_FILE_MAX_SIZE ]]; then
                                log "Reducing log data in ${MAIN_LOG_FILE}."
                                TEMP_FILE=${TEMP_DIR}/tcpdump-${RANDOM}.tmp
                                SKIP=$(( (SIZE - (MAIN_LOG_FILE_MAX_SIZE - MAIN_LOG_FILE_ALLOWANCE)) / DD_BLOCK_SIZE ))

                                if
                                        dd "bs=${DD_BLOCK_SIZE}" "skip=${SKIP}" "if=${MAIN_LOG_FILE}" "of=${TEMP_FILE}" \
                                        && cat "${TEMP_FILE}" > "${MAIN_LOG_FILE}" \
                                        && rm -f "${TEMP_FILE}"
                                then
                                        log "Done."
                                else
                                        log "Failed.  Something went wrong."
                                fi
                        fi
                fi
        done

        log "Shutting down."
        check_tcpdump && stop_tcpdump
        log "----------------------------------------"
}

# Start.

main



All times are GMT -5. The time now is 04:52 AM.