Cogitatio materialis est

How to visualize tcpdump with GraphViz ?

7th Nov 2013 Tags: #awk #bash #makefile #tcpdump

Let's assume, you want to visualize your network's map/structure. How could you get it? Well.. there're plenty ways. For example, you can use Gephi, Scapy and other tools and scripts. Or you can do it by yourself :)

I'll show you one of such ways - how to visualise tcpdump output with help of GraphViz and bash only.

What do we have?

Suppose, all you have - a tcpdump log. You could get it from wherever you want, all you can make it by yourself.

What do we need?

We need a graph of network:

  • PCs (identified by IP) are nodes
  • If one PC sended data to anothere - nodes should be connected

We should get something like this: Example of network's graph

A bit of theory

We would use:

  • tcpdump
  • graphViz
  • bash

If you are already familiar with with these technologies, you could skip next 2 chapters ;)

Tcpdump

tcpdump - utility to dump traffic on a network. There're plenty of tutorials how to work with it (one, two, three). I will show only the most basic and common commands.

Basic args

  • -i any : Listen on all interfaces just to see if you're seeing any traffic.
  • -i eth0: Listen on eth0 interface.
  • -n : Don't resolve hostnames.
  • -nn : Don't resolve hostnames or port names.
  • -X : Show the packet's contents in both hex and ASCII.
  • -v, -vv, -vvv : Increase the amount of packet information you get back.
  • -c x : Only get x number of packets and then stop.
  • -S : Print absolute sequence numbers.
  • -w file.pcap : save the packet data to a file.pcap for later analysis. Data will be saved in binary mode, so you could later get ALL nedeed info from such file.
  • -r file.pcap : read from a saved packet file.pcap rather than to read packets from a network interface. You could also specified any needed options, like -n, -v, -S and so on.
  • -t : Don't print a timestamp on each dump line.

Basic usage

  1. tcpdump -nS -i eth0 : see the basics info without many options
  2. tcpdump -nnvvS -i eht0 : see a good amount of traffic, with verbosity and no name help
  3. tcpdump -c 100 -i eht0 -w dump.pcap : save 100 packages into file dump.pcap for later analysis
  4. tcpdump -nntr dump.pcap : get only desirable information from saved dump file.
    -nnt will print smth like: IP 192.168.1.1.22 > 192.168.1.2.50673: UDP, length 10.

Look at man pages for more information ;)

GraphViz

graphviz - rich set of graph drawing tools. Actually, it has deadly simple syntax.
Just look :

  $ cat simple_graph.dot
  digraph my_first_graph {
      A -> B [ label = "Edge A to B" ];
      B -> C [ label = "Edge B to C" ];
      A [label="Node A"];
      A -> {C ; D}
  }

  # compile it:
  cat simple_graph.dot | dot -Tsvg -o simple_graph.svg

And you will get your first graph: My First graph with graphviz

There are several layout programs for drawing graphs, like

  • dot (filter for hierarchical layouts of graphs)
  • neato (filter for symmetric layouts of graphs)
  • circo (for symmetric layouts of graphs)
  • and other

Basic args fot dot

  • -T <xxx> : xxx is a likely format to convert (ps, svg, png, gif and so on)
  • -K <layout> : use diffrenet layout (dot, neato, circo, fdp ...)
  • -o <outfilename.extension> : output file path and extension

There're good official tutorials for beginners for dot and neato.

Let's Code it!

Going back to the original problem, I think you already know what we need to do:

  1. Parse a tcpdump log and grep all IPs
  2. Put them into file with graphviz-dot-syntax
  3. Render an image
  4. Profit!

Parse script

There're some existing solution for this problem, like this or this one, but in my case (if you already have a tcpdump log to visualize) they were too complex or didn't work at all. So, I write it by myself.

Here is snippet how to grep IPv4 and put them in a .dot file format

grep -E -- "IP\ " "$FILE" | awk ' BEGIN { e="(([0-9]{1,3}.){3})([0-9]{1,3}).*" }
{
    printf "\"%s\" -> \"%s\";\n", gensub(e, "\\1\\3", "1", $3), gensub(e, "\\1\\3", "1", $5)
}' >> "$TMP"

There is no sense to post here all the code. Please, download it from github page.
And there is also basic usage example.

Render

Now, we have 2 files with IPv4 and IPv6 which can be converted into img/pdf/svg/etcs. IPv4 one looks like:

digraph tcpdump_graph_ip4 {
    "10.0.0.50" -> "10.0.0.255";
    "10.0.0.50" -> "192.168.0.57";
    "10.0.0.50" -> "224.0.0.251";
    ...
}

You can render it manually, or with help of universal Makefile
(be careful to copy it as is, because you should use tabs for indents in Makefiles):

LAYOUT=circo
SOURCES = $(wildcard *.dot)
TARGETS = $(SOURCES:.dot=.svg)

%.svg:%.dot
    dot -Tsvg -K${LAYOUT} "$^" -o "$@"

all: $(TARGETS)

clean:
  rm -f $(TARGETS)

As for me, I just run make and... Profit!

One of resulting images (svg; may be useful to open in new tab): Map of local network