Eigir
Eigir

Reputation: 2099

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. :)

Upvotes: 8

Views: 29969

Answers (4)

anishsane
anishsane

Reputation: 20980

& here is a grep only solution:

tcpdump -l -i eth1 -n -c 5 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

Note -l, in case you don't want to limit the number of packets using -c.

Upvotes: 1

F. Hauri  - Give Up GitHub
F. Hauri - Give Up GitHub

Reputation: 70772

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'

Upvotes: 1

Steve
Steve

Reputation: 54392

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) }'

Upvotes: 9

anishsane
anishsane

Reputation: 20980

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.

Upvotes: 2

Related Questions