After my Tcpdump script for storing MAC-IPv6 address bindings via the Duplicate Address Detection messages (link) and an analysis of the realibility of them (here), I had the idea of a Linux script that analyzes the Tcpdump output for obtaining some IPv6 address statistics. It should not show concrete bindings between MAC- and IPv6-addresses, but the number of different kind of IPv6 addresses, such as link-local or global-unicast addresses, built with or without EUI-64, etc.
In the following, I will present my script and will show the results after running it through the DAD logs of a whole month (March 2014) in a BYOD-WLAN with more than 100 clients.
Global Unicast vs. Link-Local
The script reads out a DAD logfile which must be generated like presented in my frist blogpost for DAD messages (link). It then “analyzes” them with several simple shell commands such as sed, sort, uniq, and grep, all piped behind each other. In the end, a “wc -l” counts the number of addresses for each request. The main idead was to analyze the distribution of global unicast and link-local IPv6 addresses, separated to “EUI-64 based address” or “random (e.g. privacy extended) address”.
As an example, this is the command that counts the global unicast IPv6 addresses:
1 |
global=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep -v fe80:: | wc -l` |
My script is the following. Make it executable (chmod u+x ipv6addrstats) and call it with the dad-logfile specified:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#!/bin/bash ####################################################################### #Author: Johannes Weber (johannes@webernetz.net) # #Homepage: http://weberblog.net # #Last Modified: 2014-05-01 # ####################################################################### printf "Basic statistics for IPv6 addresses:\n\n" #Call without any options displays the following lines if [ $# == 0 ] then printf "Takes a textfile that is the output of Tcpdump such as:\n" printf "tcpdump -e -n -tttt -r dad.pcap > dad.txt\n\n" printf "Syntax: ipv6addrstats FILE\n\n" exit 0 fi #Get the numbers of addresses #Yes, I know that it is not efficient to read out the file each time completely new. ;) dadmessages=`cat $1 | wc -l` mac=`cat $1 | sed -r s/.{27}// | sed s/.\>.*// | sort | uniq | wc -l` ipv6=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | wc -l` global=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep -v fe80:: | wc -l` globaleui64=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep -v fe80:: | grep ff:fe | wc -l` globalwithouteui64=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep -v fe80:: | grep -v ff:fe | wc -l` linklocal=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep fe80:: | wc -l` linklocaleui64=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep fe80:: | grep ff:fe | wc -l` linklocalwithouteui64=`cat $1 | sed s/.*has.// | sed s/,.*// | sort | uniq | grep fe80:: | grep -v ff:fe | wc -l` #Print the table printf "%5d %s\n\n" $dadmessages "DAD Messages that contain:" printf "%5d %s\n" $mac "MAC Addresses" printf "%5d %s\t\t\t%s\n\n" $ipv6 "IPv6 Addresses" "--> Examples:" printf "%5d %s\t\t\t%s\n" $global "Global Unicast" "--> 2001:db8::" printf "%5d %s\t%s\n" $globaleui64 "Global Unicast with EUI-64" "--> 2001:db8::1234:56ff:fe78:90ab" printf "%5d %s\t%s\n\n" $globalwithouteui64 "Global Unicast without EUI-64" "--> 2001:db8::46c2:3294:6336:dedb" printf "%5d %s\t\t\t%s\n" $linklocal "Link-Local" "--> fe80::" printf "%5d %s\t\t%s\n" $linklocaleui64 "Link-Local with EUI-64" "--> fe80::1234:56ff:fe78:90ab" printf "%5d %s\t\t%s\n\n" $linklocalwithouteui64 "Link-Local without EUI-64" "--> fe80::46c2:3294:6336:dedb (e.g. Windows)" |
Here is a sample output from my DAD sniffing over a month (published here) with the ipv6addrstats script. It shows the number of MAC- and IPv6-addresses, separated into Global Unicast and Link-Local. Furthermore, both categories are split into “ff:fe” types of addresses and “random looking” ones. (Note that Windows uses static but random IIDs for its link-local addresses in addition to the privacy extensions for global unicast addresses):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
weberjoh@jw-nb09:~$ ./ipv6addrstats dad.txt Basic statistics for IPv6 addresses: 16123 DAD Messages that contain: 117 MAC Addresses 3195 IPv6 Addresses --> Examples: 3047 Global Unicast --> 2001:db8:: 81 Global Unicast with EUI-64 --> 2001:db8::1234:56ff:fe78:90ab 2966 Global Unicast without EUI-64 --> 2001:db8::46c2:3294:6336:dedb 148 Link-Local --> fe80:: 78 Link-Local with EUI-64 --> fe80::1234:56ff:fe78:90ab 70 Link-Local without EUI-64 --> fe80::46c2:3294:6336:dedb (e.g. Windows) |
That’s it. ;)
Though my script does not visualize these values, I drew a simple graph with Excel to better interpret these values. Here it is. The most interesting part is the wide usage of the Privacy Extensions:
However, I was interested in a few more analysis of the DAD file that go beyond a simple count of addresses. Here they are:
How many IPv6 addresses per MAC?
I was interested in the following: How many IPv6 addresses has a single MAC address created? Of course, I can produce a detailed list with all concrete IPv6 addresses per MAC address, but I was almost interested in the mere count of addresses. Here is my selection:
1 |
cat dad.txt | sed -r s/.{27}// | sed s/\>.*has.// | sed s/,.*// | sort | uniq | sed -e "s/\s.*//" | uniq -c | sort -h -r |
This produces the following output. (I only list the first and last few entries here). Really interesting that some clients generated a few hundred IPv6 addresses over the measured 30 days:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
weberjoh@jw-nb09:~$ cat dad.txt | sed -r s/.{27}// | sed s/\>.*has.// | sed s/,.*// | sort | uniq | sed -e "s/\s.*//" | uniq -c | sort -h -r 591 b8:ff:61:74:e7:dd 366 3c:d0:f8:c9:4c:f6 279 58:1f:aa:5e:cc:e4 241 90:27:e4:35:38:a8 226 80:ea:96:13:1f:05 86 a4:c3:61:78:7b:8d 82 98:b8:e3:46:cf:20 70 0c:77:1a:bd:73:4e 45 00:1b:63:c7:2a:16 [...] 2 00:60:6e:d5:96:82 2 00:60:6e:42:ad:2c 2 00:1d:d9:36:c6:40 1 94:35:0a:19:66:90 1 38:e7:d8:bc:49:1c 1 28:98:7b:03:1a:75 1 00:60:6e:d5:a4:d1 |
A similar selection is the count of DAD messages per MAC address. The request looks like that:
1 |
cat dad.txt | sed -r s/.{27}// | sed s/.\>.*// | sort | uniq -c | sort -h -r |
And here is the sample output, of course with mostly the same MAC addresses in the first rows compared to the sample output above:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
weberjoh@jw-nb09:~$ cat dad.txt | sed -r s/.{27}// | sed s/.\>.*// | sort | uniq -c | sort -h -r 1756 b8:ff:61:74:e7:dd 1588 fc:a1:3e:c5:5e:6e 1085 3c:d0:f8:c9:4c:f6 871 00:60:6e:d5:96:82 818 58:1f:aa:5e:cc:e4 705 90:27:e4:35:38:a8 650 80:ea:96:13:1f:05 420 00:1d:e0:28:74:5d 357 c8:14:79:c4:f7:fc 341 00:16:d4:b8:9a:71 [...] 3 6e:bd:7b:97:72:0c 3 00:60:6e:d5:a4:d1 3 00:60:6e:d5:9b:38 3 00:1f:e1:83:af:9d 2 ca:48:b1:16:ed:72 2 00:1d:d9:36:c6:40 1 28:98:7b:03:1a:75 |
Featured image “Ask and ye shall receive…” by Nic McPhee is licensed under CC BY-SA 2.0.