Using PERL to Interpret NetFlow Show Command Output

Author
Peter Welcher
Architect, Operations Technical Advisor

For example, “show ip cache flow” produces output like the following:

rtr1841#show ip cac flo 
IP packet size distribution (98655 total packets): 
1-32   64   96  128  160  192  224  256  288  320  352  384  416  448  480 
.000 .921 .014 .010 .040 .000 .001 .002 .000 .000 .000 .000 .000 .000 .000 512  544  576 1024 1536 2048 2560 3072 3584 4096 4608 
.000 .000 .000 .000 .007 .000 .000 .000 .000 .000 .000 

IP Flow Switching Cache, 278544 bytes 
17 active, 4079 inactive, 19629 added 
715321 ager polls, 0 flow alloc failures 
Active flows timeout in 30 minutes 
Inactive flows timeout in 15 seconds 
IP Sub Flow Cache, 25736 bytes 
15 active, 1009 inactive, 16457 added, 16457 added to flow 
0 alloc failures, 0 force free 
1 chunk, 1 chunk added 
last clearing of statistics never 
Protocol         Total    Flows   Packets Bytes  Packets Active(Sec) Idle(Sec) 
——–         Flows     /Sec     /Flow  /Pkt     /Sec     /Flow     /Flow 
TCP-WWW             38      0.0         5    45      0.0       0.2       1.4 
TCP-other           38      0.0         3    48      0.0       0.9      15.4 
UDP-NTP            909      0.0         1    76      0.0       0.0      15.5 
UDP-other        17822      0.2         1   115      0.3       1.8      15.5 
ICMP                 2      0.0         1   204      0.0       0.0      15.4 
GRE                  1      0.0        12    80      0.0      18.9      15.3 
IP-other           210      0.0       353    60      1.0    1627.3       3.4 
Total:           19020      0.2         5    73      1.4      19.6      15.3 

SrcIf         SrcIPaddress    DstIf         DstIPaddress    Pr SrcP DstP  Pkts 
Fa0/0.77      10.20.77.1      Null          224.0.0.10      58 0000 0000    69 
Fa0/0.3       192.168.1.4     Null          224.0.1.40      11 0002 01F0     1 
Fa0/0.17      192.168.1.4     Null          224.0.1.40      11 0002 01F0     1 
Fa0/0.3       192.168.1.4     Null          224.0.1.39      11 0001 01F0     1 
Fa0/0.17      192.168.1.4     Null          224.0.1.39      11 0001 01F0     1 

SrcIf         SrcIPaddress    DstIf         DstIPaddress    Pr SrcP DstP  Pkts 
Fa0/0         192.168.1.4     Null          224.0.1.40      11 0002 01F0     1 
Fa0/1         192.168.1.3     Null          224.0.1.40      11 0002 01F0     1 
Fa0/1         192.168.1.3     Null          224.0.1.39      11 0001 01F0     1 
Fa0/0         192.168.1.4     Null          224.0.1.39      11 0001 01F0     1 
Fa0/1         192.168.1.130   Null          192.168.1.255   11 19F6 19F6     8 
Fa0/0.17      10.20.17.1      Null          224.0.0.10      58 0000 0000    66 
Fa0/0         10.20.1.1       Null          224.0.0.10      58 0000 0000    70 
Fa0/0.3       10.20.3.1       Null          224.0.0.10      58 0000 0000    68 
Fa0/1         192.168.1.3     Null          224.0.0.10      58 0000 0000    66 
Fa0/0.17      10.20.254.1     Null          224.0.1.40      11 01F0 01F0     1 
Fa0/0.3       10.20.254.1     Null          224.0.1.40      11 01F0 01F0     1 
Fa0/0.3       10.20.254.1     Null          224.0.1.39      11 01F0 01F0     1 
Fa0/0.17      10.20.254.1     Null          224.0.1.39      11 01F0 01F0     1 
Fa0/0         10.20.254.1     Null          224.0.1.39      11 01F0 01F0     1 
Fa0/0         10.20.254.1     Null          224.0.1.40      11 01F0 01F0     1 
Fa0/0         192.168.1.131   Local         10.20.1.15      06 05A1 0017    44 

SrcIf         SrcIPaddress    DstIf         DstIPaddress    Pr SrcP DstP  Pkts 
Fa0/0.77      10.20.77.1      Null          224.0.0.10      58 0000 0000    86 
Fa0/1         192.168.1.130   Null          192.168.1.255   11 19F6 19F6     1 
Fa0/0.17      10.20.17.1      Null          224.0.0.10      58 0000 0000    82 
Fa0/0         10.20.1.1       Null          224.0.0.10      58 0000 0000    84 
Fa0/0.3       10.20.3.1       Null          224.0.0.10      58 0000 0000    82 
Fa0/0         192.168.1.131   Local         10.20.1.15      06 06F2 0017    74 
Fa0/1         192.168.1.3     Null          224.0.0.10      58 0000 0000    81 
rtr1841#

The one problem with that is most of us aren’t quick at mental gymnastics to convert hex to decimal. And we all know what IP protocols 6 and 17 are, don’t we?

To help with interpreting such output, I wrote a PERL script. Here is sample output from it

rtr1841#show ip cac flo
IP packet size distribution (98655 total packets):
1-32   64   96  128  160  192  224  256  288  320  352  384  416  448  480
.000 .921 .014 .010 .040 .000 .001 .002 .000 .000 .000 .000 .000 .000 .000512  544  576 1024 1536 2048 2560 3072 3584 4096 4608
.000 .000 .000 .000 .007 .000 .000 .000 .000 .000 .000

IP Flow Switching Cache, 278544 bytes
17 active, 4079 inactive, 19629 added
715321 ager polls, 0 flow alloc failures
Active flows timeout in 30 minutes
Inactive flows timeout in 15 seconds
IP Sub Flow Cache, 25736 bytes
15 active, 1009 inactive, 16457 added, 16457 added to flow
0 alloc failures, 0 force free
1 chunk, 1 chunk added
last clearing of statistics never
Protocol         Total    Flows   Packets Bytes  Packets Active(Sec) Idle(Sec)
——–         Flows     /Sec     /Flow  /Pkt     /Sec     /Flow     /Flow
TCP-WWW             38      0.0         5    45      0.0       0.2       1.4
TCP-other           38      0.0         3    48      0.0       0.9      15.4
UDP-NTP            909      0.0         1    76      0.0       0.0      15.5
UDP-other        17822      0.2         1   115      0.3       1.8      15.5
ICMP                 2      0.0         1   204      0.0       0.0      15.4
GRE                  1      0.0        12    80      0.0      18.9      15.3
IP-other           210      0.0       353    60      1.0    1627.3       3.4
Total:           19020      0.2         5    73      1.4      19.6      15.3

SrcIf         SrcIPaddress    DstIf         DstIPaddress    Pr      SrcP            DstP             Pkts
Fa0/0.77      10.20.77.1      Null          224.0.0.10      EIGRP   Reserved        Reserved           69
Fa0/0.3       192.168.1.4     Null          224.0.1.40      UDP     compressnet     pim-rp-disc         1
Fa0/0.17      192.168.1.4     Null          224.0.1.40      UDP     compressnet     pim-rp-disc         1
Fa0/0.3       192.168.1.4     Null          224.0.1.39      UDP     tcpmux          pim-rp-disc         1
Fa0/0.17      192.168.1.4     Null          224.0.1.39      UDP     tcpmux          pim-rp-disc         1
Fa0/0         192.168.1.4     Null          224.0.1.40      UDP     compressnet     pim-rp-disc         1
Fa0/1         192.168.1.3     Null          224.0.1.40      UDP     compressnet     pim-rp-disc         1
Fa0/1         192.168.1.3     Null          224.0.1.39      UDP     tcpmux          pim-rp-disc         1
Fa0/0         192.168.1.4     Null          224.0.1.39      UDP     tcpmux          pim-rp-disc         1
Fa0/1         192.168.1.130   Null          192.168.1.255   UDP     6646            6646                8
Fa0/0.17      10.20.17.1      Null          224.0.0.10      EIGRP   Reserved        Reserved           66
Fa0/0         10.20.1.1       Null          224.0.0.10      EIGRP   Reserved        Reserved           70
Fa0/0.3       10.20.3.1       Null          224.0.0.10      EIGRP   Reserved        Reserved           68
Fa0/1         192.168.1.3     Null          224.0.0.10      EIGRP   Reserved        Reserved           66
Fa0/0.17      10.20.254.1     Null          224.0.1.40      UDP     pim-rp-disc     pim-rp-disc         1
Fa0/0.3       10.20.254.1     Null          224.0.1.40      UDP     pim-rp-disc     pim-rp-disc         1
Fa0/0.3       10.20.254.1     Null          224.0.1.39      UDP     pim-rp-disc     pim-rp-disc         1
Fa0/0.17      10.20.254.1     Null          224.0.1.39      UDP     pim-rp-disc     pim-rp-disc         1
Fa0/0         10.20.254.1     Null          224.0.1.39      UDP     pim-rp-disc     pim-rp-disc         1
Fa0/0         10.20.254.1     Null          224.0.1.40      UDP     pim-rp-disc     pim-rp-disc         1
Fa0/0         192.168.1.131   Local         10.20.1.15      TCP     cadis-1         telnet             44
Fa0/0.77      10.20.77.1      Null          224.0.0.10      EIGRP   Reserved        Reserved           86
Fa0/1         192.168.1.130   Null          192.168.1.255   UDP     6646            6646                1
Fa0/0.17      10.20.17.1      Null          224.0.0.10      EIGRP   Reserved        Reserved           82
Fa0/0         10.20.1.1       Null          224.0.0.10      EIGRP   Reserved        Reserved           84
Fa0/0.3       10.20.3.1       Null          224.0.0.10      EIGRP   Reserved        Reserved           82
Fa0/0         192.168.1.131   Local         10.20.1.15      TCP     prodigy-intrnet telnet             74
Fa0/1         192.168.1.3     Null          224.0.0.10      EIGRP   Reserved        Reserved           81
rtr1841#

It’s the same information, but the tail end is replaced by converting hex to decimal and then looking up names of IP protocols or assigned UDP and TCP ports based on the official assigned numbers information.

The PERL script a bit large due to the protocol / port lookup tables. Copy the text to a text file named nf.pl, and run it on captured output like the sample with hex above.

6 responses to “Using PERL to Interpret NetFlow Show Command Output

  1. You can run with any good PERL distribution on Windows or Linux. Active PERL is very good, free. See [url]http://www.activestate.com/activeperl/[/url]

    Yes, to use it, capture the show ip cache flow output and then run it through the PERL script.

    The router interface is included as part of the standard NetFlow information, but the show output isn’t that fancy. So you can’t get interface loading, nor time-based graphs, from this script. This is just basic what flows were seen in some period of time.

    For better reporting, you might look into the NASA sponsored FlowViewer (free web GUI front end to the CAIDA tools), it’s pretty good. Or Scrutinizer from Plixer.com, enterprise license is about $3500 I believe, it isn’t as fancy as the $100,000 tools but I hear very good things about it. It breaks out NetFlow by interface and I believe can show a stacked area graph of which applications are consuming the bandwidth. Plus it saves historical usage (summarized).

  2. I get the below message:

    C:>perl nf.pl
    Use of uninitialized value $filename in open at test1.pl line 2155.
    Use of uninitialized value $filename in concatenation (.) or string at nf.pl
    line 2155.
    Can’t open file

    C:>

  3. Try "perl nf.pl filename" where "filename" is the name of the file (captured show output from the router).

    Hey, it’s a minimal script!

  4. Hello, thanks for the script. It does not work for me either.
    I get this:

    Use of uninitialized value $line in pattern match (m//) at ./netflow.pl line 2160.
    Use of uninitialized value $line in print at ./netflow.pl line 2174.

  5. Apparently the line read failed or some error occurred. Sorry, my intent was to provide the rudiments of a script, I can’t take on troubleshooting it. Check your input and make sure only the show output is there. It may be the format of the box you captured from is problematic or changed from what it was when I wrote the script.

Leave a Reply