[flow-tools] Hack to display traffic per network

Mark Fullmer maf@eng.oar.net
Wed, 5 Sep 2001 00:56:13 -0400


What about just using flow-xlate -f and flow-stat -f8

flow-xlate -f will AND the srcaddr and dstaddr with the src_mask and
dst_mask.  flow-stat -f8 will summarize by dstaddr.

Also to get data into perl without using Dave's Cflow module try
using flow-export.

yes, I know documentation sucks.  I'm working on it.

On Wed, Aug 29, 2001 at 03:04:00PM +0800, Miguel A.L. Paraz wrote:
> This isn't elegant, but the attached patch produces flow-print output
> with '-f15' that when piped through the attached perl script, produces
> bytes of traffic per network.  I wrote this because I found that flow-print
> did not have any output formats that dealt with the destination as network,
> and not host.
> 
> I use it like: flow-filter -i11 < ft-xxxxxx | flow-print -f15 | ./netflow-sum.pl
> 
> I hope someone finds it useful.
> 
> 

> --- flow-print.c.orig	Sun Jul 15 13:02:47 2001
> +++ flow-print.c	Wed Aug 29 12:33:54 2001
> @@ -67,13 +67,14 @@
>  int format12(struct ftio *ftio, int options);
>  int format13(struct ftio *ftio, int options);
>  int format14(struct ftio *ftio, int options);
> +int format15(struct ftio *ftio, int options);
>  
>  struct jump format[] = {{format0}, {format1}, {format2},
>            {format3}, {format4}, {format5}, {format6}, {format7},
>            {format8}, {format9}, {format10}, {format11}, {format12},
> -          {format13}, {format14}, };
> +          {format13}, {format14}, {format15}};
>  
> -#define NFORMATS 15
> +#define NFORMATS 16
>  
>  void usage();
>  
> @@ -1060,3 +1061,35 @@
>  
>  }
>  
> +/*
> + * function: format15
> + * <map@internet.org.ph>
> + * make it easy to account for output by post-processing, so output in
> + * numeric form and include netmasks
> +*/
> +int format15(struct ftio *ftio, int options)
> +{
> +  struct fts3rec_v5_gen *rec;
> +  char fmt_buf1[64], fmt_buf2[64];
> +
> +  if (ftio_check_generic5(ftio) < 0)
> +    return -1;
> +
> +  while ((rec = ftio_read(ftio))) {
> +
> +    fmt_ipv4(fmt_buf1, rec->srcaddr, FMT_PAD_RIGHT);
> +
> +    fmt_ipv4(fmt_buf2, rec->dstaddr, FMT_PAD_RIGHT);
> +
> +    printf("%u %d %u %d %lu %lu\n",
> +      rec->srcaddr, rec->src_mask, rec->dstaddr, rec->dst_mask,
> +	   (u_long)rec->dPkts, (u_long)rec->dOctets);
> +
> +    if (options & FT_OPT_NOBUF)
> +      fflush(stdout);
> +
> +  } /* while */
> +
> +  return 0;
> +
> +} /* format15 */

> #!/usr/bin/perl
> #
> # netflow-sum.pl
> # post-process Netflow output to get summary per routing table network
> # which can be further be reduced to compare with the networks being sent
> # outside via BGP
> 
> use strict;
> 
> my %bytes_net;
> 
> while (defined (my $line = <STDIN>)) {
>     my ($src, $src_mask, $dst, $dst_mask, $packets, $bytes) =
> 	($line =~ (/(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d+)\n/));
> 
>     my $bitmask = 0xffffffff ^ ((1 << (32 - $dst_mask)) - 1);
>     my $key = ($dst & $bitmask) . "/" . $dst_mask;
> 
>     $bytes_net{$key} += $bytes;
> }
> 
> my @a;
> foreach my $key (keys (%bytes_net)) {
>     push (@a, [$key, $bytes_net{$key}]);
> }
> @a = sort {-($a->[1] <=> $b->[1])} @a;
> 
> foreach my $e (@a) {
>     my ($ipn, $mask) = ($e->[0] =~ m!(\d+)/(\d+)!);
> 
>     # Convert to dotted quad.  Should be a better way to do this.
>     my $t = sprintf ("%x", $ipn);
>     my @ipd;
>     for (my $i = 0; $i < 8; $i += 2) {
> 	push (@ipd, oct("0x" . substr ($t, $i, 2)));
>     }
>     my $ip = join (".", @ipd);
>     
>     
>     printf "%16s/%d %12d\n", $ip, $mask, $e->[1];
> }