Linux - NetworkingThis forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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 :-)
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.)
I think this is exactly what I’m looking for but I have a question about functionality.
Quote:
Originally Posted by konsolebox
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" &
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!
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!
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[@]}" ...
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.
Last edited by konsolebox; 10-12-2012 at 02:37 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
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
Last edited by konsolebox; 10-12-2012 at 08:58 PM.
Reason: Added fixes.
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
Last edited by konsolebox; 10-12-2012 at 09:12 PM.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.