This is what I'm using. This mostly works with 0.67. Summary-detail had to change for 0.68 to support this script. Also attached is flow-rpt2rrd which will take flow-report output and create rrd's, and flow-log2rrd which parses the output of flow-fanout to graph drops, packets, and flows. Again, I'm not sure if flow-rpt2rrd will work with the 0.67 flow-report output.

Attachment: flow-rpt2rrd
Description: Binary data

Attachment: flow-log2rrd
Description: Binary data




Attachment: flow-rptfmt
Description: Binary data



On Jul 23, 2004, at 12:06 PM, John Kristoff wrote:

Until direct html output is supported with flow-report I imagine a
number of people have written their own parsers to convert the output
to HTML.  I have hacked up one that creates familiar top 10 tables in
HTML format that appears to work for me.  Others off-list indicated
that it might be useful for them to use the methods I did so I'll post
the details here.  It seems there could be more examples of how others
are using flow-tools so hopefully this will help someone.

It's not very generic and may even have a couple of minor problems.
A pointer to something better or enhancements are of course welcome.

I hereby place any code below into the public domain.

Using the -R option to flow-capture, I run a script that, among other
things, creates a top TCP/UDP port usage report that is run like this
(where $1 is the recently rotated flow file passed to the script):

  flow-cat $1 | flow-report -s report.conf -S top-ports

To create top 10 reports (change the records option to whatever is
appropriate for you) a tcp-egress.report looks like this:

  include-filter filter.conf
  stat-report tcp-dstport-egress-octets
    type ip-destination-port
    filter tcp-egress
    output
      format ascii
      records 10
      # scale xxx if you're getting sampled flows
      path tcp-dstport-egress-octets.txt
      fields -duration
      sort +octets
      options +totals
  #
  stat-report tcp-srcport-egress-flows
    type ip-source-port
    filter tcp-egress
    output
      format ascii
      records 10
      # scale xxx if you're getting sampled flows
      path tcp-srcport-egress-octets.txt
      fields -duration
      sort +flows
      options +totals
  #
  # ...add other tcp/udp definitions as necessary
  #
  stat-definition top-ports
    report tcp-dstport-egress-octets
    report tcp-srcport-egress-flows
    #
    # ...

Create the appropriate filter.conf file that sets up the needed
primitives and definitions for the filters in report.conf.  For
example:

  # ...
  #
  filter-primitive my-netblocks
    type ip-address-prefix
    permit 192.0.2.0/24
    default deny
  #
  filter-primitive tcp
    type ip-protocol
    permit tcp
    default deny
  #
  filter-definition tcp-egress
    match ip-source-address my-netblocks
    match ip-protocol tcp
  #
  # ...

For TCP/UDP reports you can create a bunch of reports by mixing the
combination of protocol (e.g. TCP or UDP), direction (e.g. ingress
or egress), port (e.g. source or destination) and rank type (e.g. flows,
octets, packets), which should keep network analysts busy and asking
for more.

Now that those definitions are out of the way, it is time for the text
to HTML conversion.  I do this with perl and with the code below I make
some assumptions about what the output looks like.  The code may need
to be tweaked if your reports are going to output something that the
script below doesn't expect (e.g. bps or other columns).

I ended up making a command line options necessary:

  [ --type stat-report-type ]  [ --rows max-rows ] [ --key sortfield ]
  [ --title report-title ] [ --headfoot ]

--type type from stat-report-type (e.g. ip-source-port or just srcPort
for short)

--rows   the number of rows to create in the HTML table

--key    the sort field (e.g. flows, octets or packets)

--title  <caption> text for the table

and --headfoot is a boolean option if present will add the HTML header
and footer tags. You might not enable this if you are taking the output
from this script and appending it to aggregate top ports file with other
tables. I'll show an example of this shortly.

In the meantime, here is the script:

  #!/usr/bin/perl -wT
  use strict;
  $|=1;

  ### init variables to defaults
  #
  my $rows = 10;               # maximum number of rows
  my $title = "Flow Report";   # report title
  my $key = "octets";          # sort on flows/octets/packets
  my $type = "n/a";            # report type (e.g. srcPort, dstPort)
  my $headfoot = 0;            # do HTML header/footer tags?

### retrieve options
#
use Getopt::Long;
my $result = 0;
$result = GetOptions( "title=s" => \$title, # report title
"rows=i" => \$rows, # max no. of rows
"key=s" => \$key, # key (flows, packets, octets)
"type=s" => \$type, # type (e.g. srcPort, dstPort)
"headfoot" => \$headfoot # do HTML header/footer tags?
);

  my $rank = 1;   # current row/ranking in report

# doHeader
# HTML header
# if HTML header not disabled, so scripts can incorpriate into another page
if( $headfoot) {
print "<html>\n<body bgcolor=\"#ffffff\">\n<center>\n";
}

  # table header
  print "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n";
  print "<caption align=\"top\">Top $rows <b>$title</b></caption>\n";

  ### use variable to determine where to put highlighted column
  my %highlight = ( "flows"   => "",
                    "octets"  => "",
                    "packets" => ""
                  );

  ### total flow, octet and packet counts
  my %totals = ();

  # highlight key table cell in green
  $highlight{$key} = ' bgcolor="#90ee90"';

# printer column heading
print "<tr bgcolor=\"#ffffcc\" align=\"center\"><td><b>rank</b></td><td><b>$type</ b><td$highlight{'flows'}><b>flows<b></ td><td$highlight{'octets'}><b>octets</b></ td><td$highlight{'packets'}><b>packets</b></td></tr>\n";

  # highlight key column in light blue
  $highlight{$key} = ' bgcolor="#add8e6"';

  while( defined(my $input = <>) ) {
      chomp $input;

      # found a totals line, use for % output
      if( $input =~ /^# rec1: ignores,flows,octets,packets/ ) {
          $input = <>;   # get totals
          ( $totals{'flows'}, $totals{'octets'}, $totals{'packets'} ) =
              $input =~ /^\d+,(\d+),(\d+),(\d+)(?:,\w+)*$/;
          next;
      }

if( $input =~ /^\s*(#.*)?$/) { next; } # skip comments or blank lines

      my( $port, $flows, $octets, $packets) = ( "", "", "", "" );
      ( $port, $flows, $octets, $packets ) = split ( /\,/, $input, 4 );

# print a row: rank, port, flows (%), octets (%), packets (%)
printf( "<tr align=\"right\"><td>%d</td><td>%s</td>", $rank++, $port );
printf( "<td$highlight{'flows'}>%s \(%3.2f%%\)</td>", commify($flows), ($flows/$totals{'flows'})*100 );
printf( "<td$highlight{'octets'}>%s \(%3.2f%%\)</td>", commify($octets), ($octets/$totals{'octets'})*100 );
printf( "<td$highlight{'packets'}>%s \(%3.2f%%\)</td></tr>\n", commify($packets), ($packets/$totals{'packets'})*100 );
}

  # table footer
  print "</table>\n";

  # html footer
  if ($headfoot) {
      print "</center>\n</body>\n</html>\n";
  }

  exit(0);  ### EXIT SUCCESS

  ### SUB ROUTINES
  #
  # from Perl Cookbook
  sub commify {
      my $text = reverse $_[0];
      $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
      return scalar reverse $text;
  }

  ### EOF

What I do is run this script against multiple port report text files
without the --headfoot option and concatenate each output together into
one top ports report page.  Doing something like this:

cat > ${HTMLREPORT} << EOF
<html>
<body>
`cat ${HTMLHEADER}`
<center>
<table border="0" cellspacing="0" cellpadding="1">
<caption align="top"For previous 5 minutes starting at <b>${FLOWDATE}.${FLOWTIME}</b></caption>
<tr>
<td>
`${TXT2HTML} --title="TCP source ports egress by octets" --type=srcPort --rows=10 --key=octets tcp-srcport-egress-octets.txt`
</td>
<td>
<! ...>
<! also by flows and packets>
</td>
</tr>
<! ...>
<! other reports and HTML tags here as appropriate>
</table>
</center>
`cat ${HTMLFOOTER}`
EOF

${HTMLREPORT} is the resulting output HTML file containing all the
tables concatenated together.  ${HTMLHEADER} points to a file that
includes any introdoctury text/html that I want to appear at the top
of the page.  ${HTMLFOOTER} is for anything I want to appear at the
end of the page.  ${TXT2HTML} should point to the Perl script I
included above.

One last tip.  You may have noticed the ${FLOWDATE}.${FLOWTIME}
variables that get put into the outer page table.  I just pull
out that info from the rotated flow file name.  This will vary
depending on how flow-capture is storing your files (-N nesting
level parameter), but if we assume the default, the parameter
passed to the script will look something take this format if you
are using NetFlow version 5 format:

  ft-v05.YYYY-MM-DD.HHMMSS-ZONE

where

  YYYY is the year
  MM is the month
  DD is the day
  HH is the hour in 24-hour format
  MM is the minutes past the hour
  SS is the seconds past the minute
  ZONE is the timezone offset to UTC in 24-hour format

Grabbing the flow date and time the would be accomplished like this,
where $1 is the flow filename passed to the script:

  FLOWTIMESTAMP=`expr substr $1 8 17`

Using all those tips you can store the top ports HTML reports off in
their own directories nested by date and hour if necessary.  The end
of the script can update a link to the most recent.  for example:

  ln -sf ${HTMLREP} /path/to/web/directory/top-ports.html

When all is said and done, if I typed in all of the above correctly and
your setup is similar to mine, you might end up with something that looks
a little like this:

  <http://aharp.ittns.northwestern.edu/tmp/top-ports-sample.html>

John
_______________________________________________
Flow-tools mailing list
[EMAIL PROTECTED]
http://mailman.splintered.net/mailman/listinfo/flow-tools

_______________________________________________
Flow-tools mailing list
[EMAIL PROTECTED]
http://mailman.splintered.net/mailman/listinfo/flow-tools

Reply via email to