Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tcpdump: Output only source and destination addresses

Problem description:

I want to print only the source and destination address from a tcpdump[1].

Have one working solution, but believe it could be improved a lot. An example that captures 5 packets, just as an example of what I'm looking for:

tcpdump -i eth1 -n -c 5 ip | \
cut -d" " -f3,5 | \
sed -e 's/^\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\..* \([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*$/\1 > \2/'

Question:

Can this be done in any easier way? Performance is also an issue here.

[1] A part of a test if the snort home_net is correctly defined, or if we see traffic not defined in the home_net.


Solution:

Ok, thanks to everyone who have replied to this one. There have been two concerns related to the answers, one is the compatibility across different linux-versions and the second one is speed.

Here is the results on the speed test I did. First the grep-version:

time tcpdump -l -r test.dmp -n ip 2>/dev/null | grep -P -o '([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*? > ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' | grep -P -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | xargs -n 2 echo >/dev/null

real    0m5.625s
user    0m0.513s
sys     0m4.305s

Then the sed-version:

time tcpdump -n -r test.dmp ip | sed -une 's/^.* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..*$/\1 > \3/p' >/dev/null
reading from file test.dmp, link-type EN10MB (Ethernet)

real    0m0.491s
user    0m0.496s
sys     0m0.020s

And the fastest one, the awk-version:

time tcpdump -l -r test.dmp -n ip | awk '{ print gensub(/(.*)\..*/,"\\1","g",$3), $4, gensub(/(.*)\..*/,"\\1","g",$5) }' >/dev/null
reading from file test.dmp, link-type EN10MB (Ethernet)

real    0m0.093s
user    0m0.111s
sys     0m0.013s

Unfortunately I have not been able to test how compatible they are, but the awk needs gnu awk to work due to the gensub function. Anyway, all three solutions works on the two platforms I have tested them on. :)

like image 521
Eigir Avatar asked Nov 21 '12 11:11

Eigir


3 Answers

Here's one way using GNU awk:

tcpdump -i eth1 -n -c 5 ip | awk '{ print gensub(/(.*)\..*/,"\\1","g",$3), $4, gensub(/(.*)\..*/,"\\1","g",$5) }'
like image 62
Steve Avatar answered Nov 22 '22 23:11

Steve


Try this:

 tcpdump -i eth1 -n -c 5 ip 2>/dev/null | sed -r 's/.* ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).* > ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1 > \2/'

If running from a .sh script, remember to escape \1 & \2 as required.

like image 20
anishsane Avatar answered Nov 23 '22 00:11

anishsane


Warning You have to use unbuffered ou line-buffered output to monitor the output of another command like tcpdump.

But you command seem correct.

To simplify, you could:

tcpdump -i eth1 -n -c 5 ip | 
  sed -une 's/^.* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..*$/\1 > \3/p'

Notice the u switch usefull without -c 5 at tcpdump

tcpdump -ni eth1 ip | 
  sed -une 's/^.* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..*$/\1 > \3/p'
like image 21
F. Hauri Avatar answered Nov 22 '22 22:11

F. Hauri