[flow-tools] Suggested feature

Will Lotto lotto@bendigotelco.com.au
Fri, 31 Jan 2003 14:59:21 +1100


This is a multi-part message in MIME format.

------=_NextPart_000_004A_01C2C939.56628050
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: 7bit

G'day,

First, thanks everyone for their help with the redundancy thing. I've
decided to go down the path of two collectors, and just manually fail
over if one goes awry.

I've been using the corperate gateway router (a cisco 3620 with NAT) for
testing, and I've noticed it records all NAT'd traffic with the
destination of the router, and a NextHop address of the computer it's
destined to.
It does not record flows for data traveling from it's NAT to the end
computer, which means accounting via destination-address is impossible.

The suggested feature is simple, add a report to flow-stats, flow-report
and flow-print showing the Next-Hop address.


Here's a sample of (hack) code that allows me to total the traffic in
flow-stats totaling for destination being next-hop

int format8(struct fmtargs *args)
{
  struct fts3rec_offsets fo;
  struct fopd32 cur;
  struct ftver ftv;
  struct ftchash *ftch;
  struct ftchash_rec_ip ftch_recip, *ftch_recipp;
  struct fopd total;
  u_int32 hash;
  char *rec;

  ftio_get_ver(&args->ftio, &ftv);

  if (ftio_check_xfield(&args->ftio, FT_XFIELD_DPKTS |
    FT_XFIELD_DOCTETS | FT_XFIELD_FIRST | FT_XFIELD_LAST |
    FT_XFIELD_NEXTHOP)) {
    fterr_warnx("Flow record missing required field for format."); /*
FT_XFIELD_NEXTHOP changed */
    return -1;
  }

  fts3rec_compute_offsets(&fo, &ftv);

  bzero(&total, sizeof total);

  bzero(&ftch_recip, sizeof ftch_recip);

  if (!(ftch = ftchash_new(65536, sizeof (struct ftchash_rec_ip), 4,
65536))) {
    fterr_warnx("ftchash_new(): failed");
    return -1;
  }

  cur.flows = 1;

  while ((rec = ftio_read(&args->ftio))) {

    CUR_GET_PLUS_FLOWS;

    TOTAL_INC;

    ftch_recip.addr = *((u_int32*)(rec+fo.nexthop)); /* nexthop not
destination */

    hash = (ftch_recip.addr>>16) ^ (ftch_recip.addr & 0xFFFF);

    if (!(ftch_recipp = ftchash_update(ftch, &ftch_recip, hash))) {
      fterr_warnx("ftch_update(): failed");
      ftchash_free(ftch);
      return -1;
    }

    STAT_INCP(ftch_recipp);

  }

  chash_ip_dump(ftch, args->cc, args->sort_order, args->options,
&total);

  ftchash_free(ftch);

  return 0;

} /* format8 */


Thanks,

Will Lotto

------=_NextPart_000_004A_01C2C939.56628050
Content-Type: text/html;
	charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Dus-ascii">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version =
6.0.4630.0">
<TITLE>Suggested feature</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->

<P><FONT SIZE=3D2 FACE=3D"Arial">G'day,</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">First, thanks everyone for their help =
with the redundancy thing. I've decided to go down the path of two =
collectors, and just manually fail over if one goes awry.</FONT></P>

<P><FONT SIZE=3D2 FACE=3D"Arial">I've been using the corperate gateway =
router (a cisco 3620 with NAT) for testing, and I've noticed it records =
all NAT'd traffic with the destination of the router, and a NextHop =
address of the computer it's destined to.</FONT></P>

<P><FONT SIZE=3D2 FACE=3D"Arial">It does not record flows for data =
traveling from it's NAT to the end computer, which means accounting via =
destination-address is impossible.</FONT></P>

<P><FONT SIZE=3D2 FACE=3D"Arial">The suggested feature is simple, add a =
report to flow-stats, flow-report and flow-print showing the Next-Hop =
address.</FONT>
</P>
<BR>

<P><FONT SIZE=3D2 FACE=3D"Arial">Here&#8217;s a sample of (hack) code =
that allows me to total the traffic in flow-stats totaling for =
destination being next-hop</FONT></P>

<P><FONT SIZE=3D2 FACE=3D"Arial">int format8(struct fmtargs =
*args)</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">{</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; struct fts3rec_offsets =
fo;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; struct fopd32 cur;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; struct ftver ftv;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; struct ftchash *ftch;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; struct ftchash_rec_ip =
ftch_recip, *ftch_recipp;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; struct fopd total;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; u_int32 hash;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; char *rec;</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; ftio_get_ver(&amp;args-&gt;ftio, =
&amp;ftv);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; if =
(ftio_check_xfield(&amp;args-&gt;ftio, FT_XFIELD_DPKTS |</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; FT_XFIELD_DOCTETS | =
FT_XFIELD_FIRST | FT_XFIELD_LAST |</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; FT_XFIELD_NEXTHOP)) =
{</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; =
fterr_warnx(&quot;Flow record missing required field for format.&quot;); =
/* FT_XFIELD_NEXTHOP changed */</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; }</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; fts3rec_compute_offsets(&amp;fo, =
&amp;ftv);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; bzero(&amp;total, sizeof =
total);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; bzero(&amp;ftch_recip, sizeof =
ftch_recip);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; if (!(ftch =3D =
ftchash_new(65536, sizeof (struct ftchash_rec_ip), 4, 65536))) {</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; =
fterr_warnx(&quot;ftchash_new(): failed&quot;);</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; }</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; cur.flows =3D 1;</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; while ((rec =3D =
ftio_read(&amp;args-&gt;ftio))) {</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; =
CUR_GET_PLUS_FLOWS;</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; TOTAL_INC;</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; ftch_recip.addr =3D =
*((u_int32*)(rec+fo.nexthop)); /* nexthop not destination */</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; hash =3D =
(ftch_recip.addr&gt;&gt;16) ^ (ftch_recip.addr &amp; 0xFFFF);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; if (!(ftch_recipp =
=3D ftchash_update(ftch, &amp;ftch_recip, hash))) {</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
fterr_warnx(&quot;ftch_update(): failed&quot;);</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
ftchash_free(ftch);</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return =
-1;</FONT>

<BR><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; }</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp;&nbsp;&nbsp; =
STAT_INCP(ftch_recipp);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; }</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; chash_ip_dump(ftch, args-&gt;cc, =
args-&gt;sort_order, args-&gt;options, &amp;total);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; ftchash_free(ftch);</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">&nbsp; return 0;</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">} /* format8 */</FONT>
</P>
<BR>

<P><FONT SIZE=3D2 FACE=3D"Arial">Thanks,</FONT>
</P>

<P><FONT SIZE=3D2 FACE=3D"Arial">Will Lotto</FONT>
</P>

</BODY>
</HTML>
------=_NextPart_000_004A_01C2C939.56628050--