Skip to content

Instantly share code, notes, and snippets.

@akhepcat
Last active May 31, 2017 06:04
Show Gist options
  • Save akhepcat/e4dfcf9c04b56eb600f0ef25bf2f9cb9 to your computer and use it in GitHub Desktop.
Save akhepcat/e4dfcf9c04b56eb600f0ef25bf2f9cb9 to your computer and use it in GitHub Desktop.
a script to tcpdump only uniquely seen IP addresses
#!/bin/bash
DBFILE=ipcapuniq.log
if [ -z "${1}" ]
then
echo "$0 [iface] {expr....}"
exit 1
fi
ifaces=$(ip link show | grep UP | cut -f 2 -d: )
ifaces=$(echo $ifaces)
IFACE=${1}
if [ -n "${ifaces##*$IFACE*}" ]
then
echo "invalid interface '${IFACE}'"
echo "one of: ${ifaces}"
exit 1
fi
shift
CAPEXP=${*}
# test mawk / awk for line-buffering
INTERACTIVE=$(awk -W interactive 'BEGIN{0}' 2>&1)
# gawk doesn't line-buffer, so we set interactive only for mawk/awk
INTERACTIVE=${INTERACTIVE:+XXXXX}
INTERACTIVE=${INTERACTIVE:--W interactive}
INTERACTIVE=${INTERACTIVE//XXXXX/}
tcpdump -l -i "${IFACE}" -nn "${CAPEXP}" 2>&1 | \
awk ${INTERACTIVE} -v dbfile="${DBFILE}" \
'BEGIN {
while(( getline line<dbfile) > 0 ) {
if ( seen[line]!=1 ) {
print line > "/dev/stderr";
seen[line]=1;
};
};
close(dbfile);
};
match($2,/^IP6$/) {
split($3,ipArr,".");
ip6=ipArr[1];
if (seen[ip6]!=1) {
print ip6 >> dbfile;
fflush(dbfile);
print ip6;
seen[ip6]=1;
};
};
match($2,/^IP$/) {
split($3,ipArr,".");
ip=ipArr[1]"."ipArr[2]"."ipArr[3]"."ipArr[4];
if (seen[ip]!=1) {
print ip >> dbfile;
fflush(dbfile);
print ip;
seen[ip]=1;
};
};'
# end
@akhepcat
Copy link
Author

akhepcat commented May 30, 2017

For tychotithonus:

  • the BEGIN section reads any existing entries from the previous log and seeds the uniq database.
  • the /IP/ section looks for lines that contain that regex, and strips the IP address out, printing and pushing into the database if it's not seen

This is somewhat dependent on [gm]?awk, and the output of tcpdump, of course.

Should work for IPv4 or IPv6.

@akhepcat
Copy link
Author

  • removed extraneous 'tee' now that we're using awk to append to the dbfile directly. Just needed to 'close' the dbfile first, and then reopen it as append later on. we flush at each write as well, because we don't want interrupts to only partially write data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment