/*
 * Copyright (c) 2002 Mark Fullmer and The Ohio State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      $Id: ftstat.c,v 1.44 2005/05/10 15:48:12 maf Exp $
 */

#include "ftconfig.h"
#include "ftlib.h"

#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stddef.h>
#include <syslog.h>
#include <dirent.h>
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <zlib.h>

#if HAVE_STRINGS_H
 #include <strings.h>
#endif
#if HAVE_STRING_H
  #include <string.h>
#endif

#if !HAVE_STRSEP
  char    *strsep (char **, const char *);
#endif

#if HAVE_LL_STRTOUL
  #define strtoull strtoul
#endif /* HAVE_LL_STRTOULL */

#define FMT_SYM_LEN 64

/*
 * ****  Datastructures and other implementation notes  ***
 *
 * Each report requires
 *
 *   struct ftstat_rpt_n which is allocated dynamically at run time.
 *  
 *   ftstat_rpt_n_new() -   allocated ftstat_rpt_n
 *   ftstat_rpt_n_accum() - called for each flow
 *   ftstat_rpt_n_calc()  - final calculations after all flows
 *   ftstat_rpt_n_dump()  - report to file
 *   ftstat_rpt_n_free()  - free storage allocated by ftstat_rpt_n_new()
 *     and others during the report run.
 *
 * The reports are grouped by a definition.  Typically the caller will
 * invoke all reports in a group by calling ftstat_def_new(),
 * ftstat_def_accum(), ftstat_def_calc(), ftstat_def_dump(), and
 * ftstat_def_free().
 *
 * The reports in the configuration file are stored in a linked
 * list of ftstat_rpt with the head in struct ftstat.
 *
 * The definitions in the configuration file are stored in a linked
 * list of ftstat_def with the head in struct ftstat.
 *
 * Each definition contains a linked list of ftstat_rpt_item
 * which points to a report (struct ftstat_rpt).
 *
 * Definitions reference reports.  Initially the report name is stored
 * in the definition and then when EOF is reached resolve_reports()
 * is called to fill in the pointers.
 *
 * The config file can reference a filter file and a tag file.  These
 * are loaded when the first tag or filter is specified.
 *
 * Each report can have a filter and a definition can have a filter
 * for all the reports.  Configuration of both is allowed.
 *
 * Each definition can invoke a tag definition. (add tags)
 *
 * Each definition can invoke a mask definition. (replace masks)
 *
 * Each report type is defined by the enum ftstat_rpt_type
 * and then the struct typelookup (tlookup) is used to configure
 * all the other report specific data items such as its ASCII
 * name, fields required, function pointers to the report specific
 * functions, options supported, etc.
 *
 * Special note for the *ps (ie min_pps, max_pps, avg_pps, min_bps,
 *  max_bps, avg_bps) calculations.  A memory optimization exists that
 *  removes the sizeof struct ftps bytes from the end of all the hash
 *  and bucket allocations (for bucket, they're not allocated).  This
 *  means that struct _must_ exist or the subtraction bytes will end
 *  up trashing real data.  An example is ftchash_rec_int where the
 *  ftps would never be used, yet it's there so the code that subtracts
 *  it off works properly.
 *
 */

static struct fts3rec_offsets nfo;
static u_int64 *sort_i64;
static double *sort_idouble;

#define DUMP_STD_OUT()\
if (rpt->out->fields & FT_STAT_FIELD_INDEX) {\
  len += fmt_uint64(fmt_buf, rpt->idx++, FMT_JUST_LEFT);\
  comma = 1;\
}\
if (rpt->out->fields & FT_STAT_FIELD_FIRST) {\
  if (comma) fmt_buf[len++] = ',';\
  len += fmt_uint32(fmt_buf+len, rpt->time_start, FMT_JUST_LEFT);\
  comma = 1;\
}\
if (rpt->out->fields & FT_STAT_FIELD_LAST) {\
  if (comma) fmt_buf[len++] = ',';\
  len += fmt_uint32(fmt_buf+len, rpt->time_end, FMT_JUST_LEFT);\
  comma = 1;\
}\


#define CHASH_DUMP_INIT(A,B)\
  struct A *B;\
  struct tally tally;\
  char fmt_buf1[32], fmt_buf[1024];\
  int len, fmt, sort_flags, sort_offset, comma;\
  fmt = FMT_JUST_LEFT;\
  fmt_buf1[0] = fmt_buf[0] = 0;\
  bzero(&tally, sizeof tally);\
  tally.t_recs = ftch->entries;\
  if (rpt->out->options & FT_STAT_OPT_NAMES)\
    fmt |= FMT_SYM;\


#define CHASH_DUMP_STD_SORT(A) \
    if (rpt->out->sort_field == FT_STAT_FIELD_FLOWS) {\
      sort_offset = offsetof(struct A, nflows);\
      sort_flags |= FT_CHASH_SORT_64;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_OCTETS) {\
      sort_offset = offsetof(struct A, noctets);\
      sort_flags |= FT_CHASH_SORT_64;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_PACKETS) {\
      sort_offset = offsetof(struct A, npackets);\
      sort_flags |= FT_CHASH_SORT_64;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_DURATION) {\
      sort_offset = offsetof(struct A, etime);\
      sort_flags |= FT_CHASH_SORT_64;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_AVG_PPS) {\
      sort_offset = offsetof(struct A, ps.avg_pps);\
      sort_flags |= FT_CHASH_SORT_DOUBLE;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_MIN_PPS) {\
      sort_offset = offsetof(struct A, ps.min_pps);\
      sort_flags |= FT_CHASH_SORT_DOUBLE;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_MAX_PPS) {\
      sort_offset = offsetof(struct A, ps.max_pps);\
      sort_flags |= FT_CHASH_SORT_DOUBLE;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_AVG_BPS) {\
      sort_offset = offsetof(struct A, ps.avg_bps);\
      sort_flags |= FT_CHASH_SORT_DOUBLE;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_MIN_BPS) {\
      sort_offset = offsetof(struct A, ps.min_bps);\
      sort_flags |= FT_CHASH_SORT_DOUBLE;\
    } else if (rpt->out->sort_field == FT_STAT_FIELD_MAX_BPS) {\
      sort_offset = offsetof(struct A, ps.max_bps);\
      sort_flags |= FT_CHASH_SORT_DOUBLE;\
    } else {\
      fterr_errx(1,"chash_xxx_dump(): internal error");\
    }

#define CHASH_STD_OUT(A,B)\
      if ((rpt->out->options & FT_STAT_OPT_TALLY) && tally.rt_recs &&\
        (!(tally.rt_recs % rpt->out->tally))) {\
        if (rpt->all_fields & FT_STAT_FIELD_PS)\
          fprintf(fp, "#TALLY %%recs=%3.3f %%flows=%3.3f %%octets=%3.3f %%packets=%3.3f %%avg-bps=%3.3f %%avg-pps=%3.3f\n",\
            ((double)tally.rt_recs/(double)tally.t_recs)*100,\
            ((double)tally.rt_flows/(double)rpt->t_flows)*100,\
            ((double)tally.rt_octets/(double)rpt->t_octets)*100,\
            ((double)tally.rt_packets/(double)rpt->t_packets)*100,\
            (((double)tally.ravg_bps/(double)tally.rt_frecs)/\
              (double)rpt->avg_bps)*100,\
            (((double)tally.ravg_pps/(double)tally.rt_frecs)/\
              (double)rpt->avg_pps)*100);\
         else\
          fprintf(fp, "#TALLY %%recs=%3.3f %%flows=%3.3f %%octets=%3.3f %%packets=%3.3f\n",\
            ((double)tally.rt_recs/(double)tally.t_recs)*100,\
            ((double)tally.rt_flows/(double)rpt->t_flows)*100,\
            ((double)tally.rt_octets/(double)rpt->t_octets)*100,\
            ((double)tally.rt_packets/(double)rpt->t_packets)*100);\
\
      } /* tally */\
      tally.rt_flows += A->nflows;\
      tally.rt_octets += A->noctets;\
      tally.rt_packets += A->npackets;\
      tally.rt_recs ++;\
      tally.rt_frecs += A->nrecs;\
      if (rpt->all_fields & FT_STAT_FIELD_PS) {\
        tally.ravg_bps += A->ps.avg_bps * A->nrecs;\
        tally.ravg_pps += A->ps.avg_pps * A->nrecs;\
      }\
\
    if (rpt->out->fields & FT_STAT_FIELD_FLOWS) {\
      if (B) fmt_buf[len++] = ',';\
      len += fmt_uint64(fmt_buf+len, A->nflows, FMT_JUST_LEFT);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_OCTETS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += fmt_uint64(fmt_buf+len, A->noctets, FMT_JUST_LEFT);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_PACKETS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += fmt_uint64(fmt_buf+len, A->npackets, FMT_JUST_LEFT);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_DURATION) {\
      if (comma) fmt_buf[len++] = ',';\
      len += fmt_uint64(fmt_buf+len, A->etime, FMT_JUST_LEFT);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_AVG_BPS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += sprintf(fmt_buf+len, "%f", A->ps.avg_bps);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_MIN_BPS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += sprintf(fmt_buf+len, "%f", A->ps.min_bps);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_MAX_BPS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += sprintf(fmt_buf+len, "%f", A->ps.max_bps);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_AVG_PPS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += sprintf(fmt_buf+len, "%f", A->ps.avg_pps);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_MIN_PPS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += sprintf(fmt_buf+len, "%f", A->ps.min_pps);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_MAX_PPS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += sprintf(fmt_buf+len, "%f", A->ps.max_pps);\
      comma = 1;\
    }\
    if (rpt->out->fields & FT_STAT_FIELD_FRECS) {\
      if (comma) fmt_buf[len++] = ',';\
      len += fmt_uint64(fmt_buf+len, A->nrecs, FMT_JUST_LEFT);\
      comma = 1;\
    }\
    fmt_buf[len++] = '\n';\
    fmt_buf[len] = 0;\
    fputs(fmt_buf, fp);\
    if (rpt->out->records && (tally.rt_recs == rpt->out->records)) {\
      fprintf(fp, "# stop, hit record limit.\n");\
      break;\
    }

#define CHASH_STDP_OUT(A,B)\
      if ((rpt->out->options & FT_STAT_OPT_TALLY) && tally.rt_recs &&\
        (!(tally.rt_recs % rpt->out->tally))) {\
        if (rpt->all_fields & FT_STAT_FIELD_PS)\
          fprintf(fp, "#TALLY %%recs=%3.3f %%flows=%3.3f %%octets=%3.3f %%packets=%3.3f %%avg-bps=%3.3f %%avg-pps=%3.3f\n",\
            ((double)tally.rt_recs/(double)tally.t_recs)*100,\
            ((double)tally.rt_flows/(double)rpt->t_flows)*100,\
            ((double)tally.rt_octets/(double)rpt->t_octets)*100,\
            ((double)tally.rt_packets/(double)rpt->t_packets)*100,\
            (((double)tally.ravg_bps/(double)tally.rt_frecs)/\
              (double)rpt->avg_bps)*100,\
            (((double)tally.ravg_pps/(double)tally.rt_frecs)/\
              (double)rpt->avg_pps)*100);\
         else\
          fprintf(fp, "#TALLY %%recs=%3.3f %%flows=%3.3f %%octets=%3.3f %%packets=%3.3f\n",\
            ((double)tally.rt_recs/(double)tally.t_recs)*100,\
            ((double)tally.rt_flows/(double)rpt->t_flows)*100,\
            ((double)tally.rt_octets/(double)rpt->t_octets)*100,\
            ((double)tally.rt_packets/(double)rpt->t_packets)*100);\
\
      } /* tally */\
      tally.rt_flows += A->nflows;\
      tally.rt_octets += A->noctets;\
      tally.rt_packets += A->npackets;\
      tally.ravg_bps += A->ps.avg_bps * A->nrecs;\
      tally.ravg_pps += A->ps.avg_pps * A->nrecs;\
      tally.rt_recs ++;\
      tally.rt_frecs += A->nrecs;\
\
  if (rpt->out->fields & FT_STAT_FIELD_FLOWS) {\
    if (B) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->nflows / (double)rpt->t_flows)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_OCTETS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->noctets / (double)rpt->t_octets)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_PACKETS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->npackets / (double)rpt->t_packets)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_DURATION) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->etime / (double)rpt->t_duration)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_AVG_BPS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->ps.avg_bps / (double)rpt->avg_bps)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_MIN_BPS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->ps.min_bps / (double)rpt->min_bps)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_MAX_BPS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->ps.max_bps / (double)rpt->max_bps)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_AVG_PPS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->ps.avg_pps / (double)rpt->avg_pps)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_MIN_PPS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->ps.min_pps / (double)rpt->min_pps)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_MAX_PPS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += sprintf(fmt_buf+len, "%f",\
     ((double)A->ps.max_pps / (double)rpt->max_pps)*100.0);\
    comma = 1;\
  }\
  if (rpt->out->fields & FT_STAT_FIELD_FRECS) {\
    if (comma) fmt_buf[len++] = ',';\
    len += fmt_uint64(fmt_buf+len, A->nrecs, FMT_JUST_LEFT);\
    comma = 1;\
  }\
  fmt_buf[len++] = '\n';\
  fmt_buf[len] = 0;\
  fputs(fmt_buf, fp);\
  if (rpt->out->records && (tally.rt_recs == rpt->out->records)) {\
    fprintf(fp, "# stop, hit record limit.\n");\
    break;\
  }

#define NEXT_WORD(A,B)\
  for (;;) {\
    B = strsep(A, " \t");\
    if ((B && *B != 0) || (!B))\
      break;\
  }\

/*
 * A = ftstat_rpt_n (struct to allocate)
 * B = rptn (local var name for A)
 * C = hash bits
 * D = size of hash record (passed to sizeof (struct)
 * E = size of hash key
 * F = num hash recs in a chunk
 *
 */
#define STD_NEW_HASH(A,B,C,D,E,F)\
  struct A *B;\
  int slen;\
  if (!(B = (struct A*)malloc(sizeof (*B)))) {\
    fterr_warnx("malloc(rpt): failed");\
    return (struct A*)0L;\
  }\
  bzero(B, sizeof *B);\
  if (rpt->all_fields & FT_STAT_FIELD_PS)\
    slen = sizeof (struct D);\
  else\
    slen = sizeof (struct D) - sizeof (struct ftps);\
  if (!(B->ftch = ftchash_new(C, slen, E, F))) {\
    free(B);\
    fterr_warnx("ftchash_new(): failed");\
    return (struct A*)0L;\
  }\
  return B;\

/*
 * A = ftstat_rpt_n (struct to allocate)
 * B = rptn (local var name for A)
 * C = bucket size
 *
 */
#define STD_NEW_BUCKET(A,B,C,D)\
  struct A *B;\
  if (!(B = (struct A*)malloc(sizeof (*B)))) {\
    fterr_warnx("malloc(rpt): failed");\
    return (struct A*)0L;\
  }\
  bzero(B, sizeof *B);\
  if (bucket_alloc(&B->bucket, (u_int32)C, D)) {\
    fterr_warnx("bucket_alloc(): failed");\
    free(B);\
    return (struct A*)0L;\
  }\
  return B;\

#define STD_CALC_BUCKET(A,B,C)\
  struct A *B;\
  register int i;\
  if (rpt->t_recs)\
    rpt->avg_pps /= (double)rpt->t_recs;\
  if (rpt->t_recs)\
    rpt->avg_bps /= (double)rpt->t_recs;\
  B = rpt->data;\
  for (i = 0; i < C; ++i) {\
    if ((B->bucket.duration[i]) && (rpt->all_fields & FT_STAT_FIELD_PS)) {\
      B->bucket.avg_pps[i] /= (double)B->bucket.recs[i];\
      B->bucket.avg_bps[i] /= (double)B->bucket.recs[i];\
    }\
    if (B->bucket.packets[i])\
      rpt->recs ++;\
  }\
  return 0;\

/*
 * A = ftstat_rpt_n
 * B = rptn (local var name for A)
 * C = ftchash_rec_x
 * D = ftch_recn (local var name for C)
 * note rpt_66, 67 have this expanded by hand
 */
#define STD_CALC_HASH(A,B,C,D)\
  struct C *D;\
  struct A *B;\
  B = rpt->data;\
  if (rpt->t_recs)\
    rpt->avg_pps /= (double)rpt->t_recs;\
  if (rpt->t_recs)\
    rpt->avg_bps /= (double)rpt->t_recs;\
  rpt->recs = B->ftch->entries;\
  if (rpt->all_fields & FT_STAT_FIELD_PS) {\
    ftchash_first(B->ftch);\
    while ((D = ftchash_foreach(B->ftch))) {\
      if (D->etime) {\
        D->ps.avg_pps /= (double)D->nrecs;\
        D->ps.avg_bps /= (double)D->nrecs;\
      }\
    }\
  }\
  return 0;

#define STD_FREE_BUCKET(A)\
  if (A) {\
    bucket_free(&A->bucket);\
    free(A);\
  }\

#define STD_FREE_HASH(A)\
  if (A) {\
    if (A->ftch)\
      ftchash_free(A->ftch);\
    free (A);\
  }\

/*
 * A = ftstat_rpt_n
 * B = rptn (local var name for A)
 * D = size of bucket
 * KEY* = ascii key name
 */
#define STD_DUMP_BUCKET(A,B,C,SYM,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4,KEY5,KEY6);\
  bucket_dump1(fp, rpt, &B->bucket, C, SYM);\
  return 0;\

/*
 * A = ftstat_rpt_n
 * B = rptn (local var name for A)
 * C = hash dump function
 * KEY* = ascii key name
 */
#define STD_DUMP_HASH0(A,B,C,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch);\
  return 0;

#define STD_DUMP_HASH0P(A,B,C,D,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, D);\
  return 0;


#define STD_DUMP_HASH1(A,B,C,SYM1,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, SYM1);\
  return 0;

#define STD_DUMP_HASH1P(A,B,C,D,SYM1,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, SYM1, D);\
  return 0;

#define STD_DUMP_HASH2(A,B,C,SYM1,SYM2,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, SYM1, SYM2);\
  return 0;

#define STD_DUMP_HASH2P(A,B,C,D,SYM1,SYM2,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, SYM1, SYM2, D);\
  return 0;

#define STD_DUMP_HASH3(A,B,C,SYM1,SYM2,SYM3,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, SYM1, SYM2, SYM3);\
  return 0;

#define STD_DUMP_HASH4(A,B,C,SYM1,SYM2,SYM3,SYM4,KEY,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6)\
  struct A *B;\
  B = rpt->data;\
  recn_dump(fp, rpt->out->fields, KEY, KEY1, KEY2, KEY3, KEY4, KEY5, KEY6);\
  C(fp, rpt, B->ftch, SYM1, SYM2, SYM3,SYM4);\
  return 0;

#define STD_ACCUM\
  cur.dFlows64 = 1;\
  FT_RECGET_LAST(cur,rec,*fo);\
  FT_RECGET_FIRST(cur,rec,*fo);\
  FT_RECGET64_DPKTS(cur,rec,*fo);\
  FT_RECGET64_DOCTETS(cur,rec,*fo);\
  FT_RECGET_UNIX_SECS(cur,rec,*fo);\
  if (fo->xfields &  FT_XFIELD_DFLOWS) {\
    FT_RECGET64_DFLOWS(cur,rec,*fo);\
  } else {\
    cur.dFlows64 = 1;\
  }\
  if (rpt->scale) {\
    cur.dPkts64 *= rpt->scale;\
    cur.dOctets64 *= rpt->scale;\
  }\
  if (!cur.dPkts64) {\
    rpt->t_ignores ++;\
    return 0;\
  }\
  if (cur.unix_secs > rpt->time_end)\
    rpt->time_end = cur.unix_secs;\
  if (cur.unix_secs < rpt->time_start)\
    rpt->time_start = cur.unix_secs;\
  {\
  duration_tmp = (cur.Last - cur.First);\
  if (duration_tmp) {\
    rpt->t_recs ++;\
    rpt->t_duration += duration_tmp;\
    if (rpt->all_fields & FT_STAT_FIELD_PS) {\
      pps_tmp = (double)cur.dPkts64/((double)(duration_tmp)/1000.0);\
      bps_tmp = (double)cur.dOctets64*8/((double)(duration_tmp)/1000.0);\
      if (pps_tmp > rpt->max_pps)\
        rpt->max_pps = pps_tmp;\
      if ((pps_tmp < rpt->min_pps) || (!rpt->min_pps))\
        rpt->min_pps = pps_tmp;\
      rpt->avg_pps += pps_tmp;\
      if (bps_tmp > rpt->max_bps)\
        rpt->max_bps = bps_tmp;\
      if ((bps_tmp < rpt->min_bps) || (!rpt->min_bps))\
        rpt->min_bps = bps_tmp;\
      rpt->avg_bps += bps_tmp;\
    }\
  }\
  }\
  rpt->t_flows += cur.dFlows64;\
  rpt->t_octets += cur.dOctets64;\
  rpt->t_packets += cur.dPkts64;\

#define STD_ACCUM_BUCKET1(A,B)\
  struct fts3rec_all2 cur;\
  struct A *B;\
  u_int32 duration_tmp;\
  double bps_tmp, pps_tmp;\
  B = rpt->data;\
  STD_ACCUM;

#define STD_ACCUM_BUCKET2(A,B)\
  if (duration_tmp) {\
    A.duration[B] += duration_tmp;\
    A.recs[B] ++;\
    if (rpt->all_fields & FT_STAT_FIELD_PS) {\
      if (pps_tmp > A.max_pps[B])\
        A.max_pps[B] = pps_tmp;\
      if ((pps_tmp < A.min_pps[B]) || (!A.min_pps[B]))\
        A.min_pps[B] = pps_tmp;\
      A.avg_pps[B] += pps_tmp;\
      if (bps_tmp > A.max_bps[B])\
        A.max_bps[B] = bps_tmp;\
      if ((bps_tmp < A.min_bps[B]) || (!A.min_bps[B]))\
        A.min_bps[B] = bps_tmp;\
      A.avg_bps[B] += bps_tmp;\
    }\
  }\
  A.flows[B] += cur.dFlows64;\
  A.octets[B] += cur.dOctets64;\
  A.packets[B] += cur.dPkts64;\

#define STD_ACCUM_HASH1(A,B,C,D,E)\
  struct fts3rec_all2 cur;\
  struct C D, *E;\
  struct A *B;\
  u_int32 hash;\
  u_int32 duration_tmp;\
  double bps_tmp, pps_tmp;\
  bzero(&D, sizeof D);\
  B = rpt->data;\
  STD_ACCUM;

#define STD_ACCUM_HASH2(A,B,C)\
  if (!(C = ftchash_update(A->ftch, &B, hash))) {\
    fterr_warnx("ftch_update(): failed");\
    return -1;\
  }\
  STD_ACCUM_INCP(C);\

#define STD_ACCUM_INCP(A)\
  if (duration_tmp) {\
    A->etime += (duration_tmp);\
    A->nrecs ++;\
    if (rpt->all_fields & FT_STAT_FIELD_PS) {\
      if (pps_tmp > A->ps.max_pps)\
        A->ps.max_pps = pps_tmp;\
      if ((pps_tmp < A->ps.min_pps) || (!A->ps.min_pps))\
        A->ps.min_pps = pps_tmp;\
      A->ps.avg_pps += pps_tmp;\
      if (bps_tmp > A->ps.max_bps)\
        A->ps.max_bps = bps_tmp;\
      if ((bps_tmp < A->ps.min_bps) || (!A->ps.min_bps))\
        A->ps.min_bps = bps_tmp;\
      A->ps.avg_bps += bps_tmp;\
    }\
  }\
  A->nflows += cur.dFlows64;\
  A->noctets += cur.dOctets64;\
  A->npackets += cur.dPkts64;\

#define STD_CALC\
  if (rpt->t_recs)\
    rpt->avg_pps /= (double)rpt->t_recs;\
  if (rpt->t_recs)\
    rpt->avg_bps /= (double)rpt->t_recs;

#define STD_DUMP_TOTALS_HEADER\
  if (ftsrpt->all_fields & FT_STAT_FIELD_PS)\
    fprintf(fp, "# rec1: records,ignores,flows,octets,packets,duration,avg_bps,min_bps,max_bps,avg_pps,min_pps,max_pps\n");\
  else\
    fprintf(fp, "# rec1: records,ignores,flows,octets,packets,duration\n");\

#define STD_DUMP_TOTALS_VAL\
  fmt_uint64(fmt_buf, ftsrpt->recs, FMT_JUST_LEFT);\
  strcat(fmt_buf, ",");\
  fmt_uint64(fmt_tmp, ftsrpt->t_ignores, FMT_JUST_LEFT);\
  strcat(fmt_buf, fmt_tmp);\
  strcat(fmt_buf, ",");\
  fmt_uint64(fmt_tmp, ftsrpt->t_flows, FMT_JUST_LEFT);\
  strcat(fmt_buf, fmt_tmp);\
  strcat(fmt_buf, ",");\
  fmt_uint64(fmt_tmp, ftsrpt->t_octets, FMT_JUST_LEFT);\
  strcat(fmt_buf, fmt_tmp);\
  strcat(fmt_buf, ",");\
  fmt_uint64(fmt_tmp, ftsrpt->t_packets, FMT_JUST_LEFT);\
  strcat(fmt_buf, fmt_tmp);\
  strcat(fmt_buf, ",");\
  fmt_uint64(fmt_tmp, ftsrpt->t_duration, FMT_JUST_LEFT);\
  strcat(fmt_buf, fmt_tmp);\
  if (ftsrpt->all_fields & FT_STAT_FIELD_PS) {\
    fprintf(fp, "%s,%f,%f,%f,%f,%f,%f\n", fmt_buf,\
      ftsrpt->avg_bps, ftsrpt->min_bps, ftsrpt->max_bps,\
      ftsrpt->avg_pps, ftsrpt->min_pps, ftsrpt->max_pps);\
  } else {\
    fprintf(fp, "%s\n", fmt_buf);\
  }\


enum ftstat_parse_state { PARSE_STATE_UNSET, PARSE_STATE_REPORT,
                          PARSE_STATE_DEFINITION, PARSE_STATE_OUTPUT };

#define FT_STAT_OPT_PERCENT             0x001
#define FT_STAT_OPT_NAMES               0x002
#define FT_STAT_OPT_SORT                0x004
#define FT_STAT_OPT_HEADER              0x008
#define FT_STAT_OPT_XHEADER             0x010
#define FT_STAT_OPT_TOTALS              0x020
#define FT_STAT_OPT_TALLY               0x080
#define FT_STAT_OPT_TAG_MASK            0x100
#define FT_STAT_OPT_SRC_PREFIX_LEN      0x200
#define FT_STAT_OPT_SRC_PREFIX_MASK     0x400
#define FT_STAT_OPT_DST_PREFIX_LEN      0x800
#define FT_STAT_OPT_DST_PREFIX_MASK     0x1000
#define FT_STAT_OPT_ALL                 0x16FF
#define FT_STAT_OPT_GENERIC             0x00FF
#define FT_STAT_OPT_GENERIC_IP_ADDR     0x07FF
#define FT_STAT_OPT_NONE                0x0

#define FT_STAT_FIELD_INDEX      0x00000001
#define FT_STAT_FIELD_FIRST      0x00000002
#define FT_STAT_FIELD_LAST       0x00000004

#define FT_STAT_FIELD_FLOWS      0x00000010
#define FT_STAT_FIELD_OCTETS     0x00000020
#define FT_STAT_FIELD_PACKETS    0x00000040
#define FT_STAT_FIELD_DURATION   0x00000080

#define FT_STAT_FIELD_AVG_PPS    0x00000100
#define FT_STAT_FIELD_AVG_BPS    0x00000200
#define FT_STAT_FIELD_MAX_PPS    0x00000400
#define FT_STAT_FIELD_MAX_BPS    0x00000800

#define FT_STAT_FIELD_MIN_PPS    0x00001000
#define FT_STAT_FIELD_MIN_BPS    0x00002000
#define FT_STAT_FIELD_OTHER      0x00004000
#define FT_STAT_FIELD_KEY        0x00008000 /* reports with a single key */

#define FT_STAT_FIELD_KEY1       0x00010000
#define FT_STAT_FIELD_KEY2       0x00020000
#define FT_STAT_FIELD_KEY3       0x00040000
#define FT_STAT_FIELD_KEY4       0x00080000

#define FT_STAT_FIELD_KEY5       0x00100000
#define FT_STAT_FIELD_KEY6       0x00200000

#define FT_STAT_FIELD_COUNT      0x01000000 /* reports that do a count */
#define FT_STAT_FIELD_FRECS      0x02000000 /* flow records in report line */

#define FT_STAT_FIELD_PPS        0x00001500 /* any *_PPS */
#define FT_STAT_FIELD_BPS        0x00002A00 /* any *_BPS */
#define FT_STAT_FIELD_PS         (FT_STAT_FIELD_PPS|FT_STAT_FIELD_BPS)

#define FT_STAT_FIELD_GENERIC    0x0200FFF7 /* most reports */
#define FT_STAT_FIELD_GENERIC2   0x02037FF7 /* reports with 2 key fields */
#define FT_STAT_FIELD_GENERIC3   0x02077FF7 /* reports with 3 key fields */
#define FT_STAT_FIELD_GENERIC4   0x020F7FF7 /* reports with 4 key fields */
#define FT_STAT_FIELD_GENERIC5   0x021F7FF7 /* reports with 5 key fields */
#define FT_STAT_FIELD_GENERIC6   0x023F7FF7 /* reports with 6 key fields */

#define FT_STAT_SORT_ASCEND      0x1
#define FT_STAT_SORT_DESCEND     0x2

struct tally {
  u_int64 rt_flows, rt_octets, rt_packets, rt_recs, t_recs;
  double ravg_bps, ravg_pps, rt_frecs;
};

struct flow_bucket {
  u_int64 *recs, *flows, *octets, *packets, *duration;
  double *avg_pps, *avg_bps;
  double *min_pps, *min_bps;
  double *max_pps, *max_bps;
  u_int32 *index;
}; /* flow_bucket */

struct line_parser {
  enum ftstat_parse_state state;
  struct ftstat_rpt *cur_rpt;
  struct ftstat_def *cur_def;
  struct ftstat_rpt_out *cur_rpt_out;
  int lineno;
  char *buf, *fname, *word;
};

struct jump {
  char *name;
  enum ftstat_parse_state state;
  int (*func)(struct line_parser *lp, struct ftstat *ftstat);
};

struct typelookup {
  char *name;
  void* (*f_new)();
  void* (*f_accum)();
  void* (*f_calc)();
  void* (*f_dump)();
  void* (*f_free)();
  int allowed_fields; /* FT_STAT_FIELD_* */
  int allowed_options;/* FT_STAT_OPT_* */
  u_int64 xfields; /* FT_XFIELD_* */
};

struct ftstat_rpt_1 {
  u_int64 time;       /* total time in 1/1000 of flows */

  double  aflowtime;  /* average time of flow */
  double  aps;        /* average packet size */
  double  afs;        /* average flow size */
  double  apf;        /* average packets per flow */
  double  fps;        /* average flows per second */
  double  fps_real;   /* average flows per second (realtime) */

  u_int64 start;      /* earliest flow time */
  u_int64 end;        /* latest flow time */

  u_int32 time_start; /* earliest flow (realtime) */
  u_int32 time_end;   /* last flow (realtime) */

  u_int32 time_real;  /* realtime duration */

  /* average packet sizes */
  u_int64 psize32;    /* bytes/packet 1    <= p <= 32 */
  u_int64 psize64;    /* bytes/packet 32   < p <= 64  */
  u_int64 psize96; u_int64 psize128; u_int64 psize160; u_int64 psize192;
  u_int64 psize224; u_int64 psize256; u_int64 psize288; u_int64 psize320;
  u_int64 psize352; u_int64 psize384; u_int64 psize416; u_int64 psize448;
  u_int64 psize480; u_int64 psize512; u_int64 psize544; u_int64 psize576;
  u_int64 psize1024; u_int64 psize1536; u_int64 psize2048; u_int64 psize2560;
  u_int64 psize3072; u_int64 psize3584; u_int64 psize4096; u_int64 psize4608;

  /* packets per flow */
  u_int64 fpsize1;    /* packets/flow = 1 */
  u_int64 fpsize2;    /* packets/flow = 2 */
  u_int64 fpsize4;    /* packets/flow 2 < p <= 4 */
  u_int64 fpsize8;    /* packets/flow 4 < p <= 8 */
  u_int64 fpsize12; u_int64 fpsize16; u_int64 fpsize20; u_int64 fpsize24;
  u_int64 fpsize28; u_int64 fpsize32; u_int64 fpsize36; u_int64 fpsize40;
  u_int64 fpsize44; u_int64 fpsize48; u_int64 fpsize52; u_int64 fpsize60;
  u_int64 fpsize100; u_int64 fpsize200; u_int64 fpsize300; u_int64 fpsize400;
  u_int64 fpsize500; u_int64 fpsize600; u_int64 fpsize700; u_int64 fpsize800;
  u_int64 fpsize900;
  u_int64 fpsize_other; /* packets/flow 200 < p */

  /* octets per flow */
  u_int64 fosize32;     /* octets/flow 1    <= p <= 32 */
  u_int64 fosize64;     /* octets/flow 32   < p <= 64 */
  u_int64 fosize128;    /* octets/flow 64   < p <= 128 */
  u_int64 fosize256;    /* octets/flow 128   < p <= 256 */
  u_int64 fosize512; u_int64 fosize1280; u_int64 fosize2048;
  u_int64 fosize2816; u_int64 fosize3584; u_int64 fosize4352;
  u_int64 fosize5120; u_int64 fosize5888; u_int64 fosize6656;
  u_int64 fosize7424; u_int64 fosize8192; u_int64 fosize8960;
  u_int64 fosize9728; u_int64 fosize10496; u_int64 fosize11264;
  u_int64 fosize12032; u_int64 fosize12800; u_int64 fosize13568;
  u_int64 fosize14336; u_int64 fosize15104; u_int64 fosize15872;
  u_int64 fosize_other; /* octets/flow 15872   < p */

  /* time per flow */
  u_int64 ftime10;    /* time/flow 1 <= p <= 10 */
  u_int64 ftime50;    /* time/flow 10 < p <= 50 */
  u_int64 ftime100; u_int64 ftime200; u_int64 ftime500; u_int64 ftime1000;
  u_int64 ftime2000; u_int64 ftime3000; u_int64 ftime4000; u_int64 ftime5000;
  u_int64 ftime6000; u_int64 ftime7000; u_int64 ftime8000; u_int64 ftime9000;
  u_int64 ftime10000; u_int64 ftime12000; u_int64 ftime14000;
  u_int64 ftime16000; u_int64 ftime18000; u_int64 ftime20000;
  u_int64 ftime22000; u_int64 ftime24000; u_int64 ftime26000;
  u_int64 ftime28000; u_int64 ftime30000;
  u_int64 ftime_other;  /* time/flow 2000 < p */
};

struct ftstat_rpt_2 {
  int foo; /* malloc place holder */
};

struct ftstat_rpt_3 {
  struct ftchash *ftch;
};

struct ftstat_rpt_4 {
  struct ftchash *ftch;
};

struct ftstat_rpt_5 {
  struct ftchash *ftch;
};

struct ftstat_rpt_6 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_7 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_8 {
  struct ftchash *ftch;
};

struct ftstat_rpt_9 {
  struct ftchash *ftch;
};

struct ftstat_rpt_10 {
  struct ftchash *ftch;
};

struct ftstat_rpt_11 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_12 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_13 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_14 {
  struct ftchash *ftch;
};

struct ftstat_rpt_15 {
  struct ftchash *ftch;
};

struct ftstat_rpt_16 {
  struct ftchash *ftch;
};

struct ftstat_rpt_17 {
  struct ftchash *ftch;
};

struct ftstat_rpt_18 {
  struct ftchash *ftch;
};

struct ftstat_rpt_19 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_20 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_21 {
  struct ftchash *ftch;
};

struct ftstat_rpt_22 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_23 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_24 {
  struct ftchash *ftch;
};

struct ftstat_rpt_25 {
  struct ftchash *ftch;
};

struct ftstat_rpt_26 {
  struct ftchash *ftch;
};

struct ftstat_rpt_27 {
  struct ftchash *ftch;
};

struct ftstat_rpt_28 {
  struct ftchash *ftch;
};

struct ftstat_rpt_29 {
  struct ftchash *ftch;
};

struct ftstat_rpt_30 {
  struct ftchash *ftch;
};

struct ftstat_rpt_31 {
  struct ftchash *ftch;
};

struct ftstat_rpt_32 {
  struct ftchash *ftch;
};

struct ftstat_rpt_33 {
  struct ftchash *ftch;
};

struct ftstat_rpt_34 {
  struct ftchash *ftch;
};

struct ftstat_rpt_35 {
  struct ftchash *ftch;
};

struct ftstat_rpt_36 {
  struct ftchash *ftch;
};

struct ftstat_rpt_37 {
  struct ftchash *ftch;
};

struct ftstat_rpt_38 {
  struct ftchash *ftch;
};

struct ftstat_rpt_39 {
  struct ftchash *ftch;
};

struct ftstat_rpt_40 {
  struct ftchash *ftch;
};

struct ftstat_rpt_41 {
  struct ftchash *ftch;
};

struct ftstat_rpt_42 {
  struct ftchash *ftch;
};

struct ftstat_rpt_43 {
  struct ftchash *ftch;
};

struct ftstat_rpt_44 {
  struct ftchash *ftch;
};

struct ftstat_rpt_45 {
  struct ftchash *ftch;
};

struct ftstat_rpt_46 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_47 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_48 {
  struct ftchash *ftch;
};

struct ftstat_rpt_49 {
  struct ftchash *ftch;
};

struct ftstat_rpt_50 {
  struct ftchash *ftch;
};

struct ftstat_rpt_51 {
  struct ftchash *ftch;
};

struct ftstat_rpt_52 {
  struct ftchash *ftch;
};

struct ftstat_rpt_53 {
  struct ftchash *ftch;
};

struct ftstat_rpt_54 {
  struct ftchash *ftch;
};

struct ftstat_rpt_55 {
  struct ftchash *ftch;
};

struct ftstat_rpt_56 {
  struct ftchash *ftch;
};

struct ftstat_rpt_57 {
  struct ftchash *ftch;
};

struct ftstat_rpt_58 {
  struct ftchash *ftch;
};

struct ftstat_rpt_59 {
  struct ftchash *ftch;
};

struct ftstat_rpt_60 {
  struct ftchash *ftch;
};

struct ftstat_rpt_61 {
  struct ftchash *ftch;
};

struct ftstat_rpt_62 {
  struct ftchash *ftch;
};

struct ftstat_rpt_63 {
  struct ftchash *ftch;
};

struct ftstat_rpt_64 {
  struct ftchash *ftch;
};

struct ftstat_rpt_65 {
  struct flow_bucket bucket;
};

struct ftstat_rpt_66 {
  struct ftchash *ftch;
};

struct ftstat_rpt_67 {
  struct ftchash *ftch;
};

struct ftstat_rpt_68 {
  struct ftchash *ftch;
};

struct ftstat_rpt_69 {
  struct ftchash *ftch;
};

struct ftstat_rpt_70 {
  struct ftchash *ftch;
};

struct ftstat_rpt_71 {
  struct ftchash *ftch;
};

struct ftstat_rpt_72 {
  struct ftchash *ftch;
};

struct ftstat_rpt_73 {
  struct ftchash *ftch;
};

struct ftstat_rpt_74 {
  struct ftchash *ftch;
};

struct ftstat_rpt_75 {
  struct ftchash *ftch;
};

struct ftstat_rpt_76 {
  struct ftchash *ftch;
};

struct ftstat_rpt_77 {
  struct ftchash *ftch;
};

struct ftstat_rpt_78 {
  struct ftchash *ftch;
};

int parse_rpt(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_type(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_filter(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_scale(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_tag_mask(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_ip_src_addr_fmt(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_ip_dst_addr_fmt(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_output(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_options(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_sort(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_fields(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_format(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_path(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_records(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_tally(struct line_parser *lp, struct ftstat *ftstat);
int parse_rpt_out_time(struct line_parser *lp, struct ftstat *ftstat);
int parse_def(struct line_parser *lp, struct ftstat *ftstat);
int parse_def_mask(struct line_parser *lp, struct ftstat *ftstat);
int parse_def_tag(struct line_parser *lp, struct ftstat *ftstat);
int parse_def_filter(struct line_parser *lp, struct ftstat *ftstat);
int parse_def_report(struct line_parser *lp, struct ftstat *ftstat);
int parse_def_time_series(struct line_parser *lp, struct ftstat *ftstat);
int parse_include_tag(struct line_parser *lp, struct ftstat *ftstat);
int parse_include_filter(struct line_parser *lp, struct ftstat *ftstat);
int parse_include_mask(struct line_parser *lp, struct ftstat *ftstat);

void ftstat_free(struct ftstat *ftstat);
static int load_masks(struct ftstat *ftstat);
static int load_filters(struct ftstat *ftstat);
static int load_tags(struct ftstat *ftstat);
static int resolve_reports(struct ftstat *ftstat);
static int dump_ascii_header(FILE *fp, struct ftio *ftio,
  struct ftstat_def *active_def, struct ftstat_rpt *rpt);

static int recn_dump(FILE *fp, int fields, char *key, char *key1,
  char *key2, char *key3, char *key4, char *key5, char *key6);

static int sort_cmp64(const void *a, const void *b);
static int sort_cmp_double(const void *a, const void *b);
void bucket_free(struct flow_bucket *b);
int bucket_alloc(struct flow_bucket *b, u_int32 n, struct ftstat_rpt *rpt);
static int bucket_dump1(FILE *fp, struct ftstat_rpt *rpt, struct flow_bucket *b,
  u_int32 nindex, char *symfile);
static int chash_c64_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch);
static int chash_c32_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1);
static int chash_c322_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2);
static int chash_c162_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2);
static int chash_c163_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2, char *sym3);
static int chash_c164_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2, char *sym3, char *sym4);
static int chash_ip_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch);
static int chash_prefix_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, int f1);
static int chash_prefix2_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch);
static int chash_prefix16_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, int f1);
static int chash_prefix162_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2, int f1 );
static int chash_prefix216_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1);
static int chash_prefix2162_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2);
static int chash_flow1_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, char *sym2);
static int chash_flow12_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1);
static int chash_prefixh_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, int f1);
static int chash_prefix_tag_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1, int f1);
static int chash_prefix2tag2_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch, char *sym1);
static int chash_int_dump(FILE *fp, struct ftstat_rpt *rpt,
  struct ftchash *ftch);

struct ftstat_rpt_1 *ftstat_rpt_1_new(struct ftstat_rpt *rpt);
int ftstat_rpt_1_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_1_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_1_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_1_free(struct ftstat_rpt_1 *rpt);

struct ftstat_rpt_2 *ftstat_rpt_2_new(struct ftstat_rpt *rpt);
int ftstat_rpt_2_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_2_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_2_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_2_free(struct ftstat_rpt_2 *rpt);

struct ftstat_rpt_3 *ftstat_rpt_3_new(struct ftstat_rpt *rpt);
int ftstat_rpt_3_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_3_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_3_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_3_free(struct ftstat_rpt_3 *rpt);

struct ftstat_rpt_4 *ftstat_rpt_4_new(struct ftstat_rpt *rpt);
int ftstat_rpt_4_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_4_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_4_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_4_free(struct ftstat_rpt_4 *rpt);

struct ftstat_rpt_5 *ftstat_rpt_5_new(struct ftstat_rpt *rpt);
int ftstat_rpt_5_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_5_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_5_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_5_free(struct ftstat_rpt_5 *rpt);

struct ftstat_rpt_6 *ftstat_rpt_6_new(struct ftstat_rpt *rpt);
int ftstat_rpt_6_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_6_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_6_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_6_free(struct ftstat_rpt_6 *rpt);

struct ftstat_rpt_7 *ftstat_rpt_7_new(struct ftstat_rpt *rpt);
int ftstat_rpt_7_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_7_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_7_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_7_free(struct ftstat_rpt_7 *rpt);

struct ftstat_rpt_8 *ftstat_rpt_8_new(struct ftstat_rpt *rpt);
int ftstat_rpt_8_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_8_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_8_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_8_free(struct ftstat_rpt_8 *rpt);

struct ftstat_rpt_9 *ftstat_rpt_9_new(struct ftstat_rpt *rpt);
int ftstat_rpt_9_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_9_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_9_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_9_free(struct ftstat_rpt_9 *rpt);

struct ftstat_rpt_10 *ftstat_rpt_10_new(struct ftstat_rpt *rpt);
int ftstat_rpt_10_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_10_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_10_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_10_free(struct ftstat_rpt_10 *rpt);

struct ftstat_rpt_11 *ftstat_rpt_11_new(struct ftstat_rpt *rpt);
int ftstat_rpt_11_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_11_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_11_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_11_free(struct ftstat_rpt_11 *rpt);

struct ftstat_rpt_12 *ftstat_rpt_12_new(struct ftstat_rpt *rpt);
int ftstat_rpt_12_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_12_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_12_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_12_free(struct ftstat_rpt_12 *rpt);

struct ftstat_rpt_13 *ftstat_rpt_13_new(struct ftstat_rpt *rpt);
int ftstat_rpt_13_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_13_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_13_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_13_free(struct ftstat_rpt_13 *rpt);

struct ftstat_rpt_14 *ftstat_rpt_14_new(struct ftstat_rpt *rpt);
int ftstat_rpt_14_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_14_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_14_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_14_free(struct ftstat_rpt_14 *rpt);

struct ftstat_rpt_15 *ftstat_rpt_15_new(struct ftstat_rpt *rpt);
int ftstat_rpt_15_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_15_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_15_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_15_free(struct ftstat_rpt_15 *rpt);

struct ftstat_rpt_16 *ftstat_rpt_16_new(struct ftstat_rpt *rpt);
int ftstat_rpt_16_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_16_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_16_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_16_free(struct ftstat_rpt_16 *rpt);

struct ftstat_rpt_17 *ftstat_rpt_17_new(struct ftstat_rpt *rpt);
int ftstat_rpt_17_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_17_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_17_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_17_free(struct ftstat_rpt_17 *rpt);

struct ftstat_rpt_18 *ftstat_rpt_18_new(struct ftstat_rpt *rpt);
int ftstat_rpt_18_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_18_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_18_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_18_free(struct ftstat_rpt_18 *rpt);

struct ftstat_rpt_19 *ftstat_rpt_19_new(struct ftstat_rpt *rpt);
int ftstat_rpt_19_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_19_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_19_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_19_free(struct ftstat_rpt_19 *rpt);

struct ftstat_rpt_20 *ftstat_rpt_20_new(struct ftstat_rpt *rpt);
int ftstat_rpt_20_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_20_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_20_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_20_free(struct ftstat_rpt_20 *rpt);

struct ftstat_rpt_21 *ftstat_rpt_21_new(struct ftstat_rpt *rpt);
int ftstat_rpt_21_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_21_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_21_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_21_free(struct ftstat_rpt_21 *rpt);

struct ftstat_rpt_22 *ftstat_rpt_22_new(struct ftstat_rpt *rpt);
int ftstat_rpt_22_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_22_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_22_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_22_free(struct ftstat_rpt_22 *rpt);

struct ftstat_rpt_23 *ftstat_rpt_23_new(struct ftstat_rpt *rpt);
int ftstat_rpt_23_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_23_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_23_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_23_free(struct ftstat_rpt_23 *rpt);

struct ftstat_rpt_24 *ftstat_rpt_24_new(struct ftstat_rpt *rpt);
int ftstat_rpt_24_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_24_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_24_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_24_free(struct ftstat_rpt_24 *rpt);

struct ftstat_rpt_25 *ftstat_rpt_25_new(struct ftstat_rpt *rpt);
int ftstat_rpt_25_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_25_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_25_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_25_free(struct ftstat_rpt_25 *rpt);

struct ftstat_rpt_26 *ftstat_rpt_26_new(struct ftstat_rpt *rpt);
int ftstat_rpt_26_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_26_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_26_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_26_free(struct ftstat_rpt_26 *rpt);

struct ftstat_rpt_27 *ftstat_rpt_27_new(struct ftstat_rpt *rpt);
int ftstat_rpt_27_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_27_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_27_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_27_free(struct ftstat_rpt_27 *rpt);

struct ftstat_rpt_28 *ftstat_rpt_28_new(struct ftstat_rpt *rpt);
int ftstat_rpt_28_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_28_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_28_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_28_free(struct ftstat_rpt_28 *rpt);

struct ftstat_rpt_29 *ftstat_rpt_29_new(struct ftstat_rpt *rpt);
int ftstat_rpt_29_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_29_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_29_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_29_free(struct ftstat_rpt_29 *rpt);

struct ftstat_rpt_30 *ftstat_rpt_30_new(struct ftstat_rpt *rpt);
int ftstat_rpt_30_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_30_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_30_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_30_free(struct ftstat_rpt_30 *rpt);

struct ftstat_rpt_31 *ftstat_rpt_31_new(struct ftstat_rpt *rpt);
int ftstat_rpt_31_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_31_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_31_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_31_free(struct ftstat_rpt_31 *rpt);

struct ftstat_rpt_32 *ftstat_rpt_32_new(struct ftstat_rpt *rpt);
int ftstat_rpt_32_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_32_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_32_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_32_free(struct ftstat_rpt_32 *rpt);

struct ftstat_rpt_33 *ftstat_rpt_33_new(struct ftstat_rpt *rpt);
int ftstat_rpt_33_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_33_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_33_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_33_free(struct ftstat_rpt_33 *rpt);

struct ftstat_rpt_34 *ftstat_rpt_34_new(struct ftstat_rpt *rpt);
int ftstat_rpt_34_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_34_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_34_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_34_free(struct ftstat_rpt_34 *rpt);

struct ftstat_rpt_35 *ftstat_rpt_35_new(struct ftstat_rpt *rpt);
int ftstat_rpt_35_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_35_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_35_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_35_free(struct ftstat_rpt_35 *rpt);

struct ftstat_rpt_36 *ftstat_rpt_36_new(struct ftstat_rpt *rpt);
int ftstat_rpt_36_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_36_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_36_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_36_free(struct ftstat_rpt_36 *rpt);

struct ftstat_rpt_37 *ftstat_rpt_37_new(struct ftstat_rpt *rpt);
int ftstat_rpt_37_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_37_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_37_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_37_free(struct ftstat_rpt_37 *rpt);

struct ftstat_rpt_38 *ftstat_rpt_38_new(struct ftstat_rpt *rpt);
int ftstat_rpt_38_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_38_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_38_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_38_free(struct ftstat_rpt_38 *rpt);

struct ftstat_rpt_39 *ftstat_rpt_39_new(struct ftstat_rpt *rpt);
int ftstat_rpt_39_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_39_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_39_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_39_free(struct ftstat_rpt_39 *rpt);

struct ftstat_rpt_40 *ftstat_rpt_40_new(struct ftstat_rpt *rpt);
int ftstat_rpt_40_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_40_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_40_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_40_free(struct ftstat_rpt_40 *rpt);

struct ftstat_rpt_41 *ftstat_rpt_41_new(struct ftstat_rpt *rpt);
int ftstat_rpt_41_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_41_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_41_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_41_free(struct ftstat_rpt_41 *rpt);

struct ftstat_rpt_42 *ftstat_rpt_42_new(struct ftstat_rpt *rpt);
int ftstat_rpt_42_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_42_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_42_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_42_free(struct ftstat_rpt_42 *rpt);

struct ftstat_rpt_43 *ftstat_rpt_43_new(struct ftstat_rpt *rpt);
int ftstat_rpt_43_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_43_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_43_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_43_free(struct ftstat_rpt_43 *rpt);

struct ftstat_rpt_44 *ftstat_rpt_44_new(struct ftstat_rpt *rpt);
int ftstat_rpt_44_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_44_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_44_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_44_free(struct ftstat_rpt_44 *rpt);

struct ftstat_rpt_45 *ftstat_rpt_45_new(struct ftstat_rpt *rpt);
int ftstat_rpt_45_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_45_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_45_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_45_free(struct ftstat_rpt_45 *rpt);

struct ftstat_rpt_46 *ftstat_rpt_46_new(struct ftstat_rpt *rpt);
int ftstat_rpt_46_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_46_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_46_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_46_free(struct ftstat_rpt_46 *rpt);

struct ftstat_rpt_47 *ftstat_rpt_47_new(struct ftstat_rpt *rpt);
int ftstat_rpt_47_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_47_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_47_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_47_free(struct ftstat_rpt_47 *rpt);

struct ftstat_rpt_48 *ftstat_rpt_48_new(struct ftstat_rpt *rpt);
int ftstat_rpt_48_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_48_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_48_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_48_free(struct ftstat_rpt_48 *rpt);

struct ftstat_rpt_49 *ftstat_rpt_49_new(struct ftstat_rpt *rpt);
int ftstat_rpt_49_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_49_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_49_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_49_free(struct ftstat_rpt_49 *rpt);

struct ftstat_rpt_50 *ftstat_rpt_50_new(struct ftstat_rpt *rpt);
int ftstat_rpt_50_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_50_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_50_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_50_free(struct ftstat_rpt_50 *rpt);

struct ftstat_rpt_51 *ftstat_rpt_51_new(struct ftstat_rpt *rpt);
int ftstat_rpt_51_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_51_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_51_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_51_free(struct ftstat_rpt_51 *rpt);

struct ftstat_rpt_52 *ftstat_rpt_52_new(struct ftstat_rpt *rpt);
int ftstat_rpt_52_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_52_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_52_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_52_free(struct ftstat_rpt_52 *rpt);

struct ftstat_rpt_53 *ftstat_rpt_53_new(struct ftstat_rpt *rpt);
int ftstat_rpt_53_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_53_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_53_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_53_free(struct ftstat_rpt_53 *rpt);

struct ftstat_rpt_54 *ftstat_rpt_54_new(struct ftstat_rpt *rpt);
int ftstat_rpt_54_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_54_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_54_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_54_free(struct ftstat_rpt_54 *rpt);

struct ftstat_rpt_55 *ftstat_rpt_55_new(struct ftstat_rpt *rpt);
int ftstat_rpt_55_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_55_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_55_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_55_free(struct ftstat_rpt_55 *rpt);

struct ftstat_rpt_56 *ftstat_rpt_56_new(struct ftstat_rpt *rpt);
int ftstat_rpt_56_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_56_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_56_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_56_free(struct ftstat_rpt_56 *rpt);

struct ftstat_rpt_57 *ftstat_rpt_57_new(struct ftstat_rpt *rpt);
int ftstat_rpt_57_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_57_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_57_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_57_free(struct ftstat_rpt_57 *rpt);

struct ftstat_rpt_58 *ftstat_rpt_58_new(struct ftstat_rpt *rpt);
int ftstat_rpt_58_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_58_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_58_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_58_free(struct ftstat_rpt_58 *rpt);

struct ftstat_rpt_59 *ftstat_rpt_59_new(struct ftstat_rpt *rpt);
int ftstat_rpt_59_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_59_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_59_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_59_free(struct ftstat_rpt_59 *rpt);

struct ftstat_rpt_60 *ftstat_rpt_60_new(struct ftstat_rpt *rpt);
int ftstat_rpt_60_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_60_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_60_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_60_free(struct ftstat_rpt_60 *rpt);

struct ftstat_rpt_61 *ftstat_rpt_61_new(struct ftstat_rpt *rpt);
int ftstat_rpt_61_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_61_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_61_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_61_free(struct ftstat_rpt_61 *rpt);

struct ftstat_rpt_62 *ftstat_rpt_62_new(struct ftstat_rpt *rpt);
int ftstat_rpt_62_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_62_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_62_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_62_free(struct ftstat_rpt_62 *rpt);

struct ftstat_rpt_63 *ftstat_rpt_63_new(struct ftstat_rpt *rpt);
int ftstat_rpt_63_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_63_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_63_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_63_free(struct ftstat_rpt_63 *rpt);

struct ftstat_rpt_64 *ftstat_rpt_64_new(struct ftstat_rpt *rpt);
int ftstat_rpt_64_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_64_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_64_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_64_free(struct ftstat_rpt_64 *rpt);

struct ftstat_rpt_65 *ftstat_rpt_65_new(struct ftstat_rpt *rpt);
int ftstat_rpt_65_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_65_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_65_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_65_free(struct ftstat_rpt_65 *rpt);

struct ftstat_rpt_66 *ftstat_rpt_66_new(struct ftstat_rpt *rpt);
int ftstat_rpt_66_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_66_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_66_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_66_free(struct ftstat_rpt_66 *rpt);

struct ftstat_rpt_67 *ftstat_rpt_67_new(struct ftstat_rpt *rpt);
int ftstat_rpt_67_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_67_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_67_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_67_free(struct ftstat_rpt_67 *rpt);

struct ftstat_rpt_68 *ftstat_rpt_68_new(struct ftstat_rpt *rpt);
int ftstat_rpt_68_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_68_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_68_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_68_free(struct ftstat_rpt_68 *rpt);

struct ftstat_rpt_69 *ftstat_rpt_69_new(struct ftstat_rpt *rpt);
int ftstat_rpt_69_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_69_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_69_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_69_free(struct ftstat_rpt_69 *rpt);

struct ftstat_rpt_70 *ftstat_rpt_70_new(struct ftstat_rpt *rpt);
int ftstat_rpt_70_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_70_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_70_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_70_free(struct ftstat_rpt_70 *rpt);

struct ftstat_rpt_71 *ftstat_rpt_71_new(struct ftstat_rpt *rpt);
int ftstat_rpt_71_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_71_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_71_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_71_free(struct ftstat_rpt_71 *rpt);

struct ftstat_rpt_72 *ftstat_rpt_72_new(struct ftstat_rpt *rpt);
int ftstat_rpt_72_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_72_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_72_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_72_free(struct ftstat_rpt_72 *rpt);

struct ftstat_rpt_73 *ftstat_rpt_73_new(struct ftstat_rpt *rpt);
int ftstat_rpt_73_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_73_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_73_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_73_free(struct ftstat_rpt_73 *rpt);

struct ftstat_rpt_74 *ftstat_rpt_74_new(struct ftstat_rpt *rpt);
int ftstat_rpt_74_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_74_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_74_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_74_free(struct ftstat_rpt_74 *rpt);

struct ftstat_rpt_75 *ftstat_rpt_75_new(struct ftstat_rpt *rpt);
int ftstat_rpt_75_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_75_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_75_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_75_free(struct ftstat_rpt_75 *rpt);

struct ftstat_rpt_76 *ftstat_rpt_76_new(struct ftstat_rpt *rpt);
int ftstat_rpt_76_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_76_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_76_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_76_free(struct ftstat_rpt_76 *rpt);

struct ftstat_rpt_77 *ftstat_rpt_77_new(struct ftstat_rpt *rpt);
int ftstat_rpt_77_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_77_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_77_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_77_free(struct ftstat_rpt_77 *rpt);

struct ftstat_rpt_78 *ftstat_rpt_78_new(struct ftstat_rpt *rpt);
int ftstat_rpt_78_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo);
int ftstat_rpt_78_calc(struct ftstat_rpt *rpt);
int ftstat_rpt_78_dump(FILE *fp, struct ftio *ftio, struct ftstat_rpt *rpt);
void ftstat_rpt_78_free(struct ftstat_rpt_78 *rpt);

struct typelookup tlookup[] = {
  {"summary-detail",
    (void*)ftstat_rpt_1_new,
    (void*)ftstat_rpt_1_accum,
    (void*)ftstat_rpt_1_calc,
    (void*)ftstat_rpt_1_dump,
    (void*)ftstat_rpt_1_free,
    FT_STAT_FIELD_OTHER|FT_STAT_FIELD_PS,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"summary-counters",
    (void*)ftstat_rpt_2_new,
    (void*)ftstat_rpt_2_accum,
    (void*)ftstat_rpt_2_calc,
    (void*)ftstat_rpt_2_dump,
    (void*)ftstat_rpt_2_free,
    FT_STAT_FIELD_PS,
    FT_STAT_OPT_HEADER|FT_STAT_OPT_XHEADER|FT_STAT_OPT_TOTALS,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"packet-size",
    (void*)ftstat_rpt_3_new,
    (void*)ftstat_rpt_3_accum,
    (void*)ftstat_rpt_3_calc,
    (void*)ftstat_rpt_3_dump,
    (void*)ftstat_rpt_3_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"octets",
    (void*)ftstat_rpt_4_new,
    (void*)ftstat_rpt_4_accum,
    (void*)ftstat_rpt_4_calc,
    (void*)ftstat_rpt_4_dump,
    (void*)ftstat_rpt_4_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"packets",
    (void*)ftstat_rpt_5_new,
    (void*)ftstat_rpt_5_accum,
    (void*)ftstat_rpt_5_calc,
    (void*)ftstat_rpt_5_dump,
    (void*)ftstat_rpt_5_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"ip-source-port",
    (void*)ftstat_rpt_6_new,
    (void*)ftstat_rpt_6_accum,
    (void*)ftstat_rpt_6_calc,
    (void*)ftstat_rpt_6_dump,
    (void*)ftstat_rpt_6_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCPORT},
  {"ip-destination-port",
    (void*)ftstat_rpt_7_new,
    (void*)ftstat_rpt_7_accum,
    (void*)ftstat_rpt_7_calc,
    (void*)ftstat_rpt_7_dump,
    (void*)ftstat_rpt_7_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTPORT},
  {"ip-source/destination-port",
    (void*)ftstat_rpt_8_new,
    (void*)ftstat_rpt_8_accum,
    (void*)ftstat_rpt_8_calc,
    (void*)ftstat_rpt_8_dump,
    (void*)ftstat_rpt_8_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCPORT|
      FT_XFIELD_DSTPORT},
  {"bps",
    (void*)ftstat_rpt_9_new,
    (void*)ftstat_rpt_9_accum,
    (void*)ftstat_rpt_9_calc,
    (void*)ftstat_rpt_9_dump,
    (void*)ftstat_rpt_9_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"pps",
    (void*)ftstat_rpt_10_new,
    (void*)ftstat_rpt_10_accum,
    (void*)ftstat_rpt_10_calc,
    (void*)ftstat_rpt_10_dump,
    (void*)ftstat_rpt_10_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"ip-destination-address-type",
    (void*)ftstat_rpt_11_new,
    (void*)ftstat_rpt_11_accum,
    (void*)ftstat_rpt_11_calc,
    (void*)ftstat_rpt_11_dump,
    (void*)ftstat_rpt_11_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR},
  {"ip-protocol",
    (void*)ftstat_rpt_12_new,
    (void*)ftstat_rpt_12_accum,
    (void*)ftstat_rpt_12_calc,
    (void*)ftstat_rpt_12_dump,
    (void*)ftstat_rpt_12_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_PROT},
  {"ip-tos",
    (void*)ftstat_rpt_13_new,
    (void*)ftstat_rpt_13_accum,
    (void*)ftstat_rpt_13_calc,
    (void*)ftstat_rpt_13_dump,
    (void*)ftstat_rpt_13_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_TOS},
  {"ip-next-hop-address",
    (void*)ftstat_rpt_14_new,
    (void*)ftstat_rpt_14_accum,
    (void*)ftstat_rpt_14_calc,
    (void*)ftstat_rpt_14_dump,
    (void*)ftstat_rpt_14_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_NEXTHOP},
  {"ip-source-address",
    (void*)ftstat_rpt_15_new,
    (void*)ftstat_rpt_15_accum,
    (void*)ftstat_rpt_15_calc,
    (void*)ftstat_rpt_15_dump,
    (void*)ftstat_rpt_15_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR},
  {"ip-destination-address",
    (void*)ftstat_rpt_16_new,
    (void*)ftstat_rpt_16_accum,
    (void*)ftstat_rpt_16_calc,
    (void*)ftstat_rpt_16_dump,
    (void*)ftstat_rpt_16_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR},
  {"ip-source/destination-address",
    (void*)ftstat_rpt_17_new,
    (void*)ftstat_rpt_17_accum,
    (void*)ftstat_rpt_17_calc,
    (void*)ftstat_rpt_17_dump,
    (void*)ftstat_rpt_17_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_DSTADDR},
  {"ip-exporter-address",
    (void*)ftstat_rpt_18_new,
    (void*)ftstat_rpt_18_accum,
    (void*)ftstat_rpt_18_calc,
    (void*)ftstat_rpt_18_dump,
    (void*)ftstat_rpt_18_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_EXADDR},
  {"input-interface",
    (void*)ftstat_rpt_19_new,
    (void*)ftstat_rpt_19_accum,
    (void*)ftstat_rpt_19_calc,
    (void*)ftstat_rpt_19_dump,
    (void*)ftstat_rpt_19_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT},
  {"output-interface",
    (void*)ftstat_rpt_20_new,
    (void*)ftstat_rpt_20_accum,
    (void*)ftstat_rpt_20_calc,
    (void*)ftstat_rpt_20_dump,
    (void*)ftstat_rpt_20_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT},
  {"input/output-interface",
    (void*)ftstat_rpt_21_new,
    (void*)ftstat_rpt_21_accum,
    (void*)ftstat_rpt_21_calc,
    (void*)ftstat_rpt_21_dump,
    (void*)ftstat_rpt_21_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_OUTPUT},
  {"source-as",
    (void*)ftstat_rpt_22_new,
    (void*)ftstat_rpt_22_accum,
    (void*)ftstat_rpt_22_calc,
    (void*)ftstat_rpt_22_dump,
    (void*)ftstat_rpt_22_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_AS},
  {"destination-as",
    (void*)ftstat_rpt_23_new,
    (void*)ftstat_rpt_23_accum,
    (void*)ftstat_rpt_23_calc,
    (void*)ftstat_rpt_23_dump,
    (void*)ftstat_rpt_23_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DST_AS},
  {"source/destination-as",
    (void*)ftstat_rpt_24_new,
    (void*)ftstat_rpt_24_accum,
    (void*)ftstat_rpt_24_calc,
    (void*)ftstat_rpt_24_dump,
    (void*)ftstat_rpt_24_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_AS|
      FT_XFIELD_DST_AS},
  {"ip-source-address/source-as",
    (void*)ftstat_rpt_25_new,
    (void*)ftstat_rpt_25_accum,
    (void*)ftstat_rpt_25_calc,
    (void*)ftstat_rpt_25_dump,
    (void*)ftstat_rpt_25_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_AS|
      FT_XFIELD_SRCADDR},
  {"ip-destination-address/source-as",
    (void*)ftstat_rpt_26_new,
    (void*)ftstat_rpt_26_accum,
    (void*)ftstat_rpt_26_calc,
    (void*)ftstat_rpt_26_dump,
    (void*)ftstat_rpt_26_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_AS|
      FT_XFIELD_DSTADDR},
  {"ip-source-address/destination-as",
    (void*)ftstat_rpt_27_new,
    (void*)ftstat_rpt_27_accum,
    (void*)ftstat_rpt_27_calc,
    (void*)ftstat_rpt_27_dump,
    (void*)ftstat_rpt_27_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DST_AS|
      FT_XFIELD_SRCADDR},
  {"ip-destination-address/destination-as",
    (void*)ftstat_rpt_28_new,
    (void*)ftstat_rpt_28_accum,
    (void*)ftstat_rpt_28_calc,
    (void*)ftstat_rpt_28_dump,
    (void*)ftstat_rpt_28_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DST_AS|
      FT_XFIELD_DSTADDR},
  {"ip-source/destination-address/source-as",
    (void*)ftstat_rpt_29_new,
    (void*)ftstat_rpt_29_accum,
    (void*)ftstat_rpt_29_calc,
    (void*)ftstat_rpt_29_dump,
    (void*)ftstat_rpt_29_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_AS|
      FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR},
  {"ip-source/destination-address/destination-as",
    (void*)ftstat_rpt_30_new,
    (void*)ftstat_rpt_30_accum,
    (void*)ftstat_rpt_30_calc,
    (void*)ftstat_rpt_30_dump,
    (void*)ftstat_rpt_30_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DST_AS|
      FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR},
  {"ip-source/destination-address/source/destination-as",
    (void*)ftstat_rpt_31_new,
    (void*)ftstat_rpt_31_accum,
    (void*)ftstat_rpt_31_calc,
    (void*)ftstat_rpt_31_dump,
    (void*)ftstat_rpt_31_free,
    FT_STAT_FIELD_GENERIC4,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_AS|
      FT_XFIELD_DST_AS|FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR},
  {"ip-source-address/input-interface",
    (void*)ftstat_rpt_32_new,
    (void*)ftstat_rpt_32_accum,
    (void*)ftstat_rpt_32_calc,
    (void*)ftstat_rpt_32_dump,
    (void*)ftstat_rpt_32_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_SRCADDR},
  {"ip-destination-address/input-interface",
    (void*)ftstat_rpt_33_new,
    (void*)ftstat_rpt_33_accum,
    (void*)ftstat_rpt_33_calc,
    (void*)ftstat_rpt_33_dump,
    (void*)ftstat_rpt_33_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_DSTADDR},
  {"ip-source-address/output-interface",
    (void*)ftstat_rpt_34_new,
    (void*)ftstat_rpt_34_accum,
    (void*)ftstat_rpt_34_calc,
    (void*)ftstat_rpt_34_dump,
    (void*)ftstat_rpt_34_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT|
      FT_XFIELD_SRCADDR},
  {"ip-destination-address/output-interface",
    (void*)ftstat_rpt_35_new,
    (void*)ftstat_rpt_35_accum,
    (void*)ftstat_rpt_35_calc,
    (void*)ftstat_rpt_35_dump,
    (void*)ftstat_rpt_35_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT|
      FT_XFIELD_DSTADDR},
  {"ip-source/destination-address/input-interface",
    (void*)ftstat_rpt_36_new,
    (void*)ftstat_rpt_36_accum,
    (void*)ftstat_rpt_36_calc,
    (void*)ftstat_rpt_36_dump,
    (void*)ftstat_rpt_36_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR},
  {"ip-source/destination-address/output-interface",
    (void*)ftstat_rpt_37_new,
    (void*)ftstat_rpt_37_accum,
    (void*)ftstat_rpt_37_calc,
    (void*)ftstat_rpt_37_dump,
    (void*)ftstat_rpt_37_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT|
      FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR},
  {"ip-source/destination-address/input/output-interface",
    (void*)ftstat_rpt_38_new,
    (void*)ftstat_rpt_38_accum,
    (void*)ftstat_rpt_38_calc,
    (void*)ftstat_rpt_38_dump,
    (void*)ftstat_rpt_38_free,
    FT_STAT_FIELD_GENERIC4,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_OUTPUT|FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR},
  {"input-interface/source-as",
    (void*)ftstat_rpt_39_new,
    (void*)ftstat_rpt_39_accum,
    (void*)ftstat_rpt_39_calc,
    (void*)ftstat_rpt_39_dump,
    (void*)ftstat_rpt_39_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_SRC_AS},
  {"input-interface/destination-as",
    (void*)ftstat_rpt_40_new,
    (void*)ftstat_rpt_40_accum,
    (void*)ftstat_rpt_40_calc,
    (void*)ftstat_rpt_40_dump,
    (void*)ftstat_rpt_40_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_DST_AS},
  {"output-interface/source-as",
    (void*)ftstat_rpt_41_new,
    (void*)ftstat_rpt_41_accum,
    (void*)ftstat_rpt_41_calc,
    (void*)ftstat_rpt_41_dump,
    (void*)ftstat_rpt_41_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT|
      FT_XFIELD_SRC_AS},
  {"output-interface/destination-as",
    (void*)ftstat_rpt_42_new,
    (void*)ftstat_rpt_42_accum,
    (void*)ftstat_rpt_42_calc,
    (void*)ftstat_rpt_42_dump,
    (void*)ftstat_rpt_42_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT|
      FT_XFIELD_DST_AS},
  {"input-interface/source/destination-as",
    (void*)ftstat_rpt_43_new,
    (void*)ftstat_rpt_43_accum,
    (void*)ftstat_rpt_43_calc,
    (void*)ftstat_rpt_43_dump,
    (void*)ftstat_rpt_43_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_SRC_AS|FT_XFIELD_DST_AS},
  {"output-interface/source/destination-as",
    (void*)ftstat_rpt_44_new,
    (void*)ftstat_rpt_44_accum,
    (void*)ftstat_rpt_44_calc,
    (void*)ftstat_rpt_44_dump,
    (void*)ftstat_rpt_44_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_OUTPUT|
      FT_XFIELD_SRC_AS|FT_XFIELD_DST_AS},
  {"input/output-interface/source/destination-as",
    (void*)ftstat_rpt_45_new,
    (void*)ftstat_rpt_45_accum,
    (void*)ftstat_rpt_45_calc,
    (void*)ftstat_rpt_45_dump,
    (void*)ftstat_rpt_45_free,
    FT_STAT_FIELD_GENERIC4,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_INPUT|
      FT_XFIELD_OUTPUT|FT_XFIELD_SRC_AS|FT_XFIELD_DST_AS},
  {"engine-id",
    (void*)ftstat_rpt_46_new,
    (void*)ftstat_rpt_46_accum,
    (void*)ftstat_rpt_46_calc,
    (void*)ftstat_rpt_46_dump,
    (void*)ftstat_rpt_46_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_ENGINE_ID},
  {"engine-type",
    (void*)ftstat_rpt_47_new,
    (void*)ftstat_rpt_47_accum,
    (void*)ftstat_rpt_47_calc,
    (void*)ftstat_rpt_47_dump,
    (void*)ftstat_rpt_47_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_ENGINE_TYPE},
  {"source-tag",
    (void*)ftstat_rpt_48_new,
    (void*)ftstat_rpt_48_accum,
    (void*)ftstat_rpt_48_calc,
    (void*)ftstat_rpt_48_dump,
    (void*)ftstat_rpt_48_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_TAG},
  {"destination-tag",
    (void*)ftstat_rpt_49_new,
    (void*)ftstat_rpt_49_accum,
    (void*)ftstat_rpt_49_calc,
    (void*)ftstat_rpt_49_dump,
    (void*)ftstat_rpt_49_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DST_TAG},
  {"source/destination-tag",
    (void*)ftstat_rpt_50_new,
    (void*)ftstat_rpt_50_accum,
    (void*)ftstat_rpt_50_calc,
    (void*)ftstat_rpt_50_dump,
    (void*)ftstat_rpt_50_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRC_TAG|
      FT_XFIELD_DST_TAG},
  {"ip-source-address/ip-source-port",
    (void*)ftstat_rpt_51_new,
    (void*)ftstat_rpt_51_accum,
    (void*)ftstat_rpt_51_calc,
    (void*)ftstat_rpt_51_dump,
    (void*)ftstat_rpt_51_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_SRCPORT},
  {"ip-source-address/ip-destination-port",
    (void*)ftstat_rpt_52_new,
    (void*)ftstat_rpt_52_accum,
    (void*)ftstat_rpt_52_calc,
    (void*)ftstat_rpt_52_dump,
    (void*)ftstat_rpt_52_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_DSTPORT},
  {"ip-destination-address/ip-source-port",
    (void*)ftstat_rpt_53_new,
    (void*)ftstat_rpt_53_accum,
    (void*)ftstat_rpt_53_calc,
    (void*)ftstat_rpt_53_dump,
    (void*)ftstat_rpt_53_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCPORT},
  {"ip-destination-address/ip-destination-port",
    (void*)ftstat_rpt_54_new,
    (void*)ftstat_rpt_54_accum,
    (void*)ftstat_rpt_54_calc,
    (void*)ftstat_rpt_54_dump,
    (void*)ftstat_rpt_54_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_DSTPORT},
  {"ip-source-address/ip-source/destination-port",
    (void*)ftstat_rpt_55_new,
    (void*)ftstat_rpt_55_accum,
    (void*)ftstat_rpt_55_calc,
    (void*)ftstat_rpt_55_dump,
    (void*)ftstat_rpt_55_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_SRCPORT|FT_XFIELD_DSTPORT},
  {"ip-destination-address/ip-source/destination-port",
    (void*)ftstat_rpt_56_new,
    (void*)ftstat_rpt_56_accum,
    (void*)ftstat_rpt_56_calc,
    (void*)ftstat_rpt_56_dump,
    (void*)ftstat_rpt_56_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCPORT|FT_XFIELD_DSTPORT},
  {"ip-source/destination-address/ip-source-port",
    (void*)ftstat_rpt_57_new,
    (void*)ftstat_rpt_57_accum,
    (void*)ftstat_rpt_57_calc,
    (void*)ftstat_rpt_57_dump,
    (void*)ftstat_rpt_57_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_DSTADDR|FT_XFIELD_DSTPORT},
  {"ip-source/destination-address/ip-destination-port",
    (void*)ftstat_rpt_58_new,
    (void*)ftstat_rpt_58_accum,
    (void*)ftstat_rpt_58_calc,
    (void*)ftstat_rpt_58_dump,
    (void*)ftstat_rpt_58_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_DSTADDR|FT_XFIELD_DSTPORT},
  {"ip-source/destination-address/ip-source/destination-port",
    (void*)ftstat_rpt_59_new,
    (void*)ftstat_rpt_59_accum,
    (void*)ftstat_rpt_59_calc,
    (void*)ftstat_rpt_59_dump,
    (void*)ftstat_rpt_59_free,
    FT_STAT_FIELD_GENERIC4,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_DSTADDR|FT_XFIELD_SRCPORT|FT_XFIELD_DSTPORT},
  {"ip-source-address/input/output-interface",
    (void*)ftstat_rpt_60_new,
    (void*)ftstat_rpt_60_accum,
    (void*)ftstat_rpt_60_calc,
    (void*)ftstat_rpt_60_dump,
    (void*)ftstat_rpt_60_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_INPUT|FT_XFIELD_OUTPUT},
  {"ip-destination-address/input/output-interface",
    (void*)ftstat_rpt_61_new,
    (void*)ftstat_rpt_61_accum,
    (void*)ftstat_rpt_61_calc,
    (void*)ftstat_rpt_61_dump,
    (void*)ftstat_rpt_61_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_INPUT|FT_XFIELD_OUTPUT},
  {"ip-source-address/source/destination-as",
    (void*)ftstat_rpt_62_new,
    (void*)ftstat_rpt_62_accum,
    (void*)ftstat_rpt_62_calc,
    (void*)ftstat_rpt_62_dump,
    (void*)ftstat_rpt_62_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_SRC_AS|FT_XFIELD_DST_AS},
  {"ip-destination-address/source/destination-as",
    (void*)ftstat_rpt_63_new,
    (void*)ftstat_rpt_63_accum,
    (void*)ftstat_rpt_63_calc,
    (void*)ftstat_rpt_63_dump,
    (void*)ftstat_rpt_63_free,
    FT_STAT_FIELD_GENERIC3,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRC_AS|FT_XFIELD_DST_AS},
  {"ip-address",
    (void*)ftstat_rpt_64_new,
    (void*)ftstat_rpt_64_accum,
    (void*)ftstat_rpt_64_calc,
    (void*)ftstat_rpt_64_dump,
    (void*)ftstat_rpt_64_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCADDR},
  {"ip-port",
    (void*)ftstat_rpt_65_new,
    (void*)ftstat_rpt_65_accum,
    (void*)ftstat_rpt_65_calc,
    (void*)ftstat_rpt_65_dump,
    (void*)ftstat_rpt_65_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTPORT|
      FT_XFIELD_SRCPORT},
  {"ip-source-address-destination-count",
    (void*)ftstat_rpt_66_new,
    (void*)ftstat_rpt_66_accum,
    (void*)ftstat_rpt_66_calc,
    (void*)ftstat_rpt_66_dump,
    (void*)ftstat_rpt_66_free,
    FT_STAT_FIELD_GENERIC|FT_STAT_FIELD_COUNT,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCADDR},
  {"ip-destination-address-source-count",
    (void*)ftstat_rpt_67_new,
    (void*)ftstat_rpt_67_accum,
    (void*)ftstat_rpt_67_calc,
    (void*)ftstat_rpt_67_dump,
    (void*)ftstat_rpt_67_free,
    FT_STAT_FIELD_GENERIC|FT_STAT_FIELD_COUNT,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCADDR},
  {"ip-source/destination-address/ip-protocol/ip-tos/ip-source/destination-port",
    (void*)ftstat_rpt_68_new,
    (void*)ftstat_rpt_68_accum,
    (void*)ftstat_rpt_68_calc,
    (void*)ftstat_rpt_68_dump,
    (void*)ftstat_rpt_68_free,
    FT_STAT_FIELD_GENERIC6,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCADDR|FT_XFIELD_PROT|FT_XFIELD_TOS|FT_XFIELD_SRCPORT|
      FT_XFIELD_DSTPORT},
  {"ip-source/destination-address/ip-protocol/ip-tos",
    (void*)ftstat_rpt_69_new,
    (void*)ftstat_rpt_69_accum,
    (void*)ftstat_rpt_69_calc,
    (void*)ftstat_rpt_69_dump,
    (void*)ftstat_rpt_69_free,
    FT_STAT_FIELD_GENERIC4,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCADDR|FT_XFIELD_PROT|FT_XFIELD_TOS},
  {"ip-source-address/source-tag",
    (void*)ftstat_rpt_70_new,
    (void*)ftstat_rpt_70_accum,
    (void*)ftstat_rpt_70_calc,
    (void*)ftstat_rpt_70_dump,
    (void*)ftstat_rpt_70_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_SRC_TAG},
  {"ip-source-address/destination-tag",
    (void*)ftstat_rpt_71_new,
    (void*)ftstat_rpt_71_accum,
    (void*)ftstat_rpt_71_calc,
    (void*)ftstat_rpt_71_dump,
    (void*)ftstat_rpt_71_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_SRCADDR|
      FT_XFIELD_DST_TAG},
  {"ip-destination-address/source-tag",
    (void*)ftstat_rpt_72_new,
    (void*)ftstat_rpt_72_accum,
    (void*)ftstat_rpt_72_calc,
    (void*)ftstat_rpt_72_dump,
    (void*)ftstat_rpt_72_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRC_TAG},
  {"ip-destination-address/destination-tag",
    (void*)ftstat_rpt_73_new,
    (void*)ftstat_rpt_73_accum,
    (void*)ftstat_rpt_73_calc,
    (void*)ftstat_rpt_73_dump,
    (void*)ftstat_rpt_73_free,
    FT_STAT_FIELD_GENERIC2,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_DST_TAG},
  {"ip-source/destination-address/source/destination-tag",
    (void*)ftstat_rpt_74_new,
    (void*)ftstat_rpt_74_accum,
    (void*)ftstat_rpt_74_calc,
    (void*)ftstat_rpt_74_dump,
    (void*)ftstat_rpt_74_free,
    FT_STAT_FIELD_GENERIC4,
    FT_STAT_OPT_GENERIC_IP_ADDR,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS|FT_XFIELD_DSTADDR|
      FT_XFIELD_SRCADDR|FT_XFIELD_SRC_TAG|FT_XFIELD_DST_TAG},
  {"linear-interpolated-flows-octets-packets",
    (void*)ftstat_rpt_75_new,
    (void*)ftstat_rpt_75_accum,
    (void*)ftstat_rpt_75_calc,
    (void*)ftstat_rpt_75_dump,
    (void*)ftstat_rpt_75_free,
    FT_STAT_FIELD_FLOWS|FT_STAT_FIELD_OCTETS|FT_STAT_FIELD_PACKETS|
      FT_STAT_FIELD_KEY,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"first",
    (void*)ftstat_rpt_76_new,
    (void*)ftstat_rpt_76_accum,
    (void*)ftstat_rpt_76_calc,
    (void*)ftstat_rpt_76_dump,
    (void*)ftstat_rpt_76_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"last",
    (void*)ftstat_rpt_77_new,
    (void*)ftstat_rpt_77_accum,
    (void*)ftstat_rpt_77_calc,
    (void*)ftstat_rpt_77_dump,
    (void*)ftstat_rpt_77_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},
  {"duration",
    (void*)ftstat_rpt_78_new,
    (void*)ftstat_rpt_78_accum,
    (void*)ftstat_rpt_78_calc,
    (void*)ftstat_rpt_78_dump,
    (void*)ftstat_rpt_78_free,
    FT_STAT_FIELD_GENERIC,
    FT_STAT_OPT_GENERIC,
    FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS|FT_XFIELD_FIRST|FT_XFIELD_LAST|
      FT_XFIELD_UNIX_SECS|FT_XFIELD_UNIX_NSECS},

  {(char*)0L, 0, (void*)0L},
};


static struct jump pjump[] = {
          {"include-mask", 0, parse_include_mask},
          {"include-tag", 0, parse_include_tag},
          {"include-filter", 0, parse_include_filter},
          {"stat-report", 0, parse_rpt},
          {"type", PARSE_STATE_REPORT, parse_rpt_type},
          {"filter", PARSE_STATE_REPORT, parse_rpt_filter},
          {"scale", PARSE_STATE_REPORT, parse_rpt_scale},
          {"output", PARSE_STATE_REPORT, parse_rpt_output},
          {"tag-mask", PARSE_STATE_REPORT, parse_rpt_tag_mask},
          {"ip-source-address-format", PARSE_STATE_REPORT,
            parse_rpt_ip_src_addr_fmt},
          {"ip-destination-address-format", PARSE_STATE_REPORT,
            parse_rpt_ip_dst_addr_fmt},
          {"format", PARSE_STATE_OUTPUT, parse_rpt_out_format},
          {"sort", PARSE_STATE_OUTPUT, parse_rpt_out_sort},
          {"records", PARSE_STATE_OUTPUT, parse_rpt_out_records},
          {"tally", PARSE_STATE_OUTPUT, parse_rpt_out_tally},
          {"fields", PARSE_STATE_OUTPUT, parse_rpt_out_fields},
          {"options", PARSE_STATE_OUTPUT, parse_rpt_out_options},
          {"path", PARSE_STATE_OUTPUT, parse_rpt_out_path},
          {"time", PARSE_STATE_OUTPUT, parse_rpt_out_time},
          {"stat-definition", 0, parse_def},
          {"filter", PARSE_STATE_DEFINITION, parse_def_filter},
          {"tag", PARSE_STATE_DEFINITION, parse_def_tag},
          {"mask", PARSE_STATE_DEFINITION, parse_def_mask},
          {"report", PARSE_STATE_DEFINITION, parse_def_report},
          {"time-series", PARSE_STATE_DEFINITION, parse_def_time_series},
          {0, 0, 0},
          };

/*
 *************************************************************************
                              public ftstat_*
 *************************************************************************
 */


/*
 * function: ftstat_load
 *
 * Process fname into ftstat.
 *
 * returns: 0  ok
 *          <0 fail
 */
int ftstat_load(struct ftstat *ftstat, struct ftvar *ftvar, char *fname)
{
  struct stat sb;
  struct jump *jmp;
  struct line_parser lp;
  int fd, ret, found;
  char *buf, *buf2, *c;
  char sbuf[FT_LP_MAXLINE];

  ret = -1;
  buf = (char*)0L;
  bzero(&lp, sizeof lp);
  bzero(ftstat, sizeof *ftstat);

  FT_SLIST_INIT(&ftstat->defs);
  FT_SLIST_INIT(&ftstat->rpts);

  ftstat->ftvar = ftvar;

  lp.fname = fname;

  if ((fd = open(fname, O_RDONLY, 0)) < 0) {
    fterr_warn("open(%s)", fname);
    goto load_stat_out;
  }

  if (fstat(fd, &sb) < 0) {
    fterr_warn("stat(%s)", fname);
    goto load_stat_out;
  }
  
  /* allocate storage for file */
  if (!(buf = malloc(sb.st_size+1))) {
    fterr_warn("malloc()");
    goto load_stat_out;
  }

  /* read in file */
  if (read(fd, buf, sb.st_size) != sb.st_size) {
    fterr_warnx("read(%s): short", fname);
    goto load_stat_out;
  }

  /* null terminate file */
  buf[sb.st_size] = 0;

  buf2 = buf;

  for (;;) {
  
    /* rip a line */
    for (;;) {
      c = strsep(&buf2, "\n");
      ++lp.lineno;
      if ((c && *c != 0) || (!c))
        break;
    }

    /* no more lines */
    if (!c) {
      goto load_stat_done;
    }

    /* do variable substitutions first */
    if (ftvar) {
      if (ftvar_evalstr(ftvar, c, sbuf, sizeof(sbuf)) < 0) {
        fterr_warnx("ftvar_evalstr(): failed");
        goto load_stat_done;
      }
    } else {
      strncpy(sbuf, c, sizeof(sbuf));
      sbuf[sizeof(sbuf)-1] = 0;
    }

    lp.buf = sbuf;

    /* first word */
    NEXT_WORD(&lp.buf, c);

    /* whitespace only line */
    if (!c) {
      continue;
    }

    /* comment line */
    if (c && *c == '#')
      continue;

    for (jmp = pjump; jmp->name; ++jmp) {

      found = 0;

      if (((!jmp->state) || (jmp->state & lp.state))
        && (!strcasecmp(c, jmp->name))) {

        found = 1;

        if (jmp->func(&lp, ftstat))
          goto load_stat_out;

        NEXT_WORD(&lp.buf, c);

        if (c) {
          fterr_warnx("%s line %d: Unexpected \"%s\".", lp.fname, lp.lineno, c);
          goto load_stat_out;
        }

        break;

      }

    } /* test each word */

    if (!found) {
      fterr_warnx("%s line %d: Unexpected \"%s\".", lp.fname, lp.lineno, c);
      goto load_stat_out;
    }
   
  } /* more lines */

load_stat_done:

  if (resolve_reports(ftstat)) {
    fterr_warnx("resolve_reports(): failed");
    goto load_stat_out;
  }

  ret = 0;

load_stat_out:

  if (fd != -1)
    close(fd);

  if (buf)
    free(buf);

  if (ret == -1)
    ftstat_free(ftstat);

  return ret;

} /* ftstat_load */

void ftstat_free(struct ftstat *ftstat)
{
  struct ftstat_def *ftsd;
  struct ftstat_rpt *ftsr;
  struct ftstat_rpt_out *ftsro;
  struct ftstat_rpt_item *ftsrpti;

  if (ftstat->ftfil_init)
    ftfil_free(&ftstat->ftfil);

  if (ftstat->fttag_init)
    fttag_free(&ftstat->fttag);

  if (ftstat->ftmask_init)
    ftmask_free(&ftstat->ftmask);

  if (ftstat->filter_fname)
    free(ftstat->filter_fname);

  if (ftstat->tag_fname)
    free(ftstat->tag_fname);

  if (ftstat->mask_fname)
    free(ftstat->mask_fname);

  /* free each definition */
  while (!FT_SLIST_EMPTY(&ftstat->defs)) {

    ftsd = FT_SLIST_FIRST(&ftstat->defs);
    FT_SLIST_REMOVE_HEAD(&ftstat->defs, chain);

    /* free each item in the definition */
    while (!FT_STAILQ_EMPTY(&ftsd->items)) {

      ftsrpti = FT_STAILQ_FIRST(&ftsd->items);
      FT_STAILQ_REMOVE_HEAD(&ftsd->items, chain);
      free(ftsrpti->tmp_report);
      free(ftsrpti);

    }

    free(ftsd->name);
    free(ftsd);

  } /* definitions */

  /* free each report */
  while (!FT_SLIST_EMPTY(&ftstat->rpts)) {

    ftsr = FT_SLIST_FIRST(&ftstat->rpts);
    FT_SLIST_REMOVE_HEAD(&ftstat->rpts, chain);

    /* free each output in the report */
    while (!FT_STAILQ_EMPTY(&ftsr->outs)) {

      ftsro =  FT_STAILQ_FIRST(&ftsr->outs);
      FT_STAILQ_REMOVE_HEAD(&ftsr->outs, chain);
      if (ftsro->path)
        free(ftsro->path);
      free(ftsro);

    }

    free(ftsr->name);
    free(ftsr);

  } /* reports */

} /* ftstat_free */

struct ftstat_def *ftstat_def_find(struct ftstat *ftstat, char *name)
{
  struct ftstat_def *ftsd;
  int found;

  found = 0;

  FT_SLIST_FOREACH(ftsd, &ftstat->defs, chain) {

    if (!strcasecmp(name, ftsd->name))
      return ftsd;

  } /* ftsd */

  return (struct ftstat_def*)0L;

} /* ftstat_def_find */

/*
 * function: ftstat_def_test_xfields
 *
 * Check if fields in current flow are valid for a stat definition -- ie
 * the filter does not reference a field not contained in the flow.
 *
 * returns: 0 okay
 *          1 fail
 */
int ftstat_def_test_xfields(struct ftstat_def *active_def, u_int64 test)
{

  /* if the definition has tagging enabled _accum() will add the tags */
  if (active_def->ftd)
    test |= FT_XFIELD_SRC_TAG|FT_XFIELD_DST_TAG;

  if ((active_def->xfields & test) != active_def->xfields)
    return 1;
  else
    return 0;

} /* ftstat_def_test_xfields */

/*
 * function: ftstat_def_new
 *
 * Call the new method for each report.
 *
 * returns: 0 okay
 *          1 fail
 */
int ftstat_def_new(struct ftstat_def *active_def)
{
  struct ftstat_rpt *ftsrpt;
  struct ftstat_rpt_item *ftsrpti;
  struct ftstat_rpt_out *ftsro;
  int ret;

  ret = 1; /* err */

  /* foreach report in the definition */
  FT_STAILQ_FOREACH(ftsrpti, &active_def->items, chain) {

    ftsrpt = ftsrpti->rpt;

    /* initialize */
    ftsrpt->t_ignores = 0;
    ftsrpt->t_recs = 0;
    ftsrpt->t_flows = 0;
    ftsrpt->t_octets = 0;
    ftsrpt->t_packets = 0;
    ftsrpt->t_duration = 0;
    ftsrpt->t_count = 0;
    ftsrpt->time_start = 0xFFFFFFFF;
    ftsrpt->time_end = 0;
    ftsrpt->recs = 0;
    ftsrpt->avg_pps = 0;
    ftsrpt->avg_bps = 0;
    ftsrpt->max_pps = 0;
    ftsrpt->max_bps = 0;
    ftsrpt->min_pps = 0;
    ftsrpt->min_bps = 0;
    ftsrpt->all_fields = 0;

    /* foreach output in the report, sum the fields */
    FT_STAILQ_FOREACH(ftsro, &ftsrpt->outs, chain) {
      ftsrpt->all_fields |= ftsro->fields;
      /* could sort and not display */
      ftsrpt->all_fields |= ftsro->sort_field;
    }

    /* run the new function */
    if (!(ftsrpt->data = ftsrpt->f_new(ftsrpt))) {
      fterr_warnx("f_new(%s): failed.", ftsrpt->name);
      goto out;
    }

  }

  ret = 0;

out:

  return ret;

} /* ftstat_def_new */

/*
 * function: ftstat_def_accum
 *
 * Call the accum method for each report.
 *
 * returns: 0 okay
 *          <0 fail
 *          1 next report.
 */
int ftstat_def_accum(struct ftstat_def *active_def,
  char *rec, struct fts3rec_offsets *fo)
{
  struct ftver ftv;
  struct ftstat_rpt *ftsrpt;
  struct ftstat_rpt_item *ftsrpti;
  struct fts3rec_all2 cur;
  char xl_rec[FT_IO_MAXREC];
  int ret;

  FT_RECGET_UNIX_SECS(cur,rec,*fo);

  if (!active_def->start_time)
    active_def->start_time = cur.unix_secs;

  /* time series split? */
  if ((active_def->max_time && (cur.unix_secs > active_def->start_time) &&
    (cur.unix_secs - active_def->start_time) > active_def->max_time)) {

    active_def->start_time = cur.unix_secs;
    return 1;

  }

  ret = -1; /* err */

  /* if mask replacement is enabled, do it */
  if (active_def->ftmd)
    ftmask_def_eval(active_def->ftmd, rec, fo);

  /* if tagging is enabled, translate and tag */
  if (active_def->ftd) {

    /* translate to 1005 is not allready */
    if (fo->ftv.d_version != 1005) {

      ftv.d_version = 1005;
      ftrec_xlate(rec, &fo->ftv, &xl_rec, &ftv);
      rec = (char*)&xl_rec;
      fo = &nfo;

    }

    fttag_def_eval(active_def->ftd, (void*)rec);

  }
  
  /* if a filter is defined, evaluate it first */
  if (active_def->ftfd)
    if (ftfil_def_eval(active_def->ftfd, rec, fo) == FT_FIL_MODE_DENY)
      goto done;

  /* foreach report in the definition */
  FT_STAILQ_FOREACH(ftsrpti, &active_def->items, chain) {

    ftsrpt = ftsrpti->rpt;

    /*
     * if the tag mask option is set apply the masks, not this can only
     * be set if the tags exist.
     *
     */
    if (ftsrpt->options & FT_STAT_OPT_TAG_MASK) {

      /* preserve tags */
      FT_RECGET_SRC_TAG(cur,rec,*fo);
      FT_RECGET_DST_TAG(cur,rec,*fo);

      *((u_int32*)(rec+(*fo).src_tag)) &= ftsrpt->tag_mask_src;
      *((u_int32*)(rec+(*fo).dst_tag)) &= ftsrpt->tag_mask_dst;

    }

    /* if a filter is defined, evaluate */
    if (ftsrpt->ftfd)
      if (ftfil_def_eval(ftsrpt->ftfd, rec, fo) == FT_FIL_MODE_DENY)
        goto restore_tag;

    /* run the accum function */
    if (ftsrpt->f_accum(ftsrpt, rec, fo)) {
      fterr_warnx("f_accum(%s): failed.", ftsrpt->name);
      goto out;
    }

    /* restore tags */
restore_tag:
    if (ftsrpt->options & FT_STAT_OPT_TAG_MASK) {

      *((u_int32*)(rec+(*fo).src_tag)) = cur.src_tag;
      *((u_int32*)(rec+(*fo).dst_tag)) = cur.dst_tag;

    }

  }

done:

  ret = 0;

out:

  return ret;

} /* ftstat_def_accum */

/*
 * function: ftstat_def_calc
 *
 * Call the calc method for each report.
 *
 * returns: 0 okay
 *          1 fail
 */
int ftstat_def_calc(struct ftstat_def *active_def)
{
  struct ftstat_rpt *ftsrpt;
  struct ftstat_rpt_item *ftsrpti;
  int ret;

  ret = 1; /* err */

  /* foreach report in the definition */
  FT_STAILQ_FOREACH(ftsrpti, &active_def->items, chain) {

    ftsrpt = ftsrpti->rpt;

    /* run the new function */
    if (ftsrpt->f_calc(ftsrpt)) {
      fterr_warnx("f_calc(%s): failed.", ftsrpt->name);
      goto out;
    }

  }

  ret = 0;

out:

  return ret;

} /* ftstat_def_calc */

/*
 * function: ftstat_def_dump
 *
 * Call the dump method for each report.
 *
 * returns: 0 okay
 *          1 fail
 */
int ftstat_def_dump(struct ftio *ftio, struct ftstat_def *active_def)
{
  struct tm *tm;
  time_t now;
  FILE *fp;
  struct ftstat_rpt *ftsrpt;
  struct ftstat_rpt_item *ftsrpti;
  struct ftstat_rpt_out *ftsro;
  int ret, noclose, pipe, status;
  char fmt_tmp[64], fmt_buf[1024], path_buf[1024], *path_run;
  char *mode;

  noclose = 0; /* fclose fp */
  ret = 1; /* err */
  fp = (FILE*)0L;

  /* foreach report in the definition */
  FT_STAILQ_FOREACH(ftsrpti, &active_def->items, chain) {

    ftsrpt = ftsrpti->rpt;

    /* foreach output listed */
    FT_STAILQ_FOREACH(ftsro, &ftsrpt->outs, chain) {

      /* current output is this one */
      ftsrpt->out = ftsro;

      if (ftsro->path) {

        strncpy(fmt_buf, ftsro->path, sizeof(fmt_buf));
        fmt_buf[sizeof(fmt_buf)-1] = 0;

        if (ftsro->time == FT_STAT_TIME_NOW)
          now = time((time_t*)0L);
        else if (ftsro->time == FT_STAT_TIME_START)
          now = ftsrpt->time_start;
        else if (ftsro->time == FT_STAT_TIME_END)
          now = ftsrpt->time_end;
        else if (ftsro->time == FT_STAT_TIME_MID)
          now = ftsrpt->time_start + (ftsrpt->time_end - ftsrpt->time_start)/2;

        tm = localtime(&now);

        if (!(strftime(path_buf, sizeof path_buf, fmt_buf, tm))) {
          fterr_warnx("strftime(): failed");
          goto out;
        }

        if (path_buf[0] == '|') {
          pipe = 1;
          path_run = path_buf+1;
        } else {
          pipe = 0;
          path_run = path_buf;
        }

        if (!pipe) {

          if (mkpath(path_run, 0755) < 0) {
            fterr_warnx("mkpath(%s): failed", path_run);
            goto out;
          }

          /* write first interval, append the rest */
          if (!active_def->interval)
            mode = "w";
          else
            mode = "a";

          if (!(fp = fopen(path_run, mode))) {
            fterr_warn("fopen(%s)", path_run);
            goto out;
          }

          noclose = 0;

        } else { /* pipe */

          if (!(fp = popen(path_run, "w"))) {
            fterr_warn("popen(%s)", path_run);
            goto out;
          }

          noclose = 0;

        } /* !pipe */

      } else { /* path specified */

        fp = stdout;
        pipe = 0;
        noclose = 1;

      }

      /* display header bits */
      dump_ascii_header(fp, ftio, active_def, ftsrpt);

      /* display totals? */
      if (ftsro->options & FT_STAT_OPT_TOTALS) {
        STD_DUMP_TOTALS_HEADER;
        STD_DUMP_TOTALS_VAL;
      }

      /* run the dump function */
      if (ftsro->f_dump(fp, ftio, ftsrpt)) {
        fterr_warnx("f_dump(%s): failed.", path_run);
        goto out;
      }

      if ((!noclose) && fp) {

        if (!pipe) {
          if (fclose(fp))
            fterr_warn("fclose(%s)", path_run);
        } else {
          status = pclose(fp);
          if (status == -1)
            fterr_warn("pclose(%s)", path_run);
          if (WIFEXITED(status))
             if (WEXITSTATUS(status) != 0)
              fterr_warnx("pclose(%s): failed exit code=%d.", path_run,
                WEXITSTATUS(status));
        }

      } /* !noclose && fp */

    } /* foreach output */

  } /* foreach report */

  ret = 0;

out:

  return ret;

} /* ftstat_def_dump */

/*
 * function: ftstat_def_free
 *
 * Call the free method for each report.
 *
 * returns: 0 okay
 *          1 fail
 */
int ftstat_def_free(struct ftstat_def *active_def)
{
  struct ftstat_rpt *ftsrpt;
  struct ftstat_rpt_item *ftsrpti;

  /* foreach report in the definition */
  FT_STAILQ_FOREACH(ftsrpti, &active_def->items, chain) {

    ftsrpt = ftsrpti->rpt;

    /* run the free function */
    ftsrpt->f_free(ftsrpt->data);

  }

  return 0;

} /* ftstat_def_free */

/*
 * function: ftstat_def_reset
 *
 * Reset reports between time series intervals
 *
 * returns: 0 okay
 *          1 fail
 */
int ftstat_def_reset(struct ftstat_def *active_def)
{

  if (ftstat_def_free(active_def)) {
    fterr_warnx("ftstat_def_free(%s): failed.", active_def->name);
    return -1;
  }

  if (ftstat_def_new(active_def)) {
    fterr_warnx("ftstat_def_new(%s): failed.", active_def->name);
    return -1;
  }

  ++active_def->interval;

  return 0;

} /* ftstat_def_reset */

/*
 * function: ftstat_list_reports
 *
 * List available reports
 *
 */

void ftstat_list_reports(FILE *out)
{
  struct typelookup *tl;

  for (tl = tlookup; tl->name; ++tl)
    fprintf(out, "  %s\n", tl->name);

} /* ftstat_list_reports */

/*
 *************************************************************************
                             parse_rpt_* 
 *************************************************************************
 */

/* 
 * function: parse_rpt
 *
 * process the 'stat-report' line.  Each report has a unique name
 * which is added to the ftstat->rpts linked list.  The current
 * report is updated in lp.  Reports by themself do nothing,
 * they must be invoked by a definition.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt(struct line_parser *lp, struct ftstat *ftstat)
{

  char *c;
  struct ftstat_rpt *ftsr;
   
  NEXT_WORD(&lp->buf, c);
  
  if (!c) {
    fterr_warnx("%s line %d: Expecting name.", lp->fname, lp->lineno);
    return -1;
  }

  /* check if it exists */
  FT_SLIST_FOREACH(ftsr, &ftstat->rpts, chain) {

    if (!strcasecmp(c, ftsr->name)) {
      fterr_warnx("%s line %d: Name (%s) previously defined.", lp->fname,
        lp->lineno, c);
      return -1;
    }

  }

  /* no, add a new entry to the list */
  if (!(ftsr = (struct ftstat_rpt*)malloc(sizeof *ftsr))) {
    fterr_warn("malloc()");
    return -1;
  }

  bzero(ftsr, sizeof *ftsr);

  FT_STAILQ_INIT(&ftsr->outs);

  if (!(ftsr->name = (char*)malloc(strlen(c)+1))) {
    fterr_warn("malloc()");
    free(ftsr);
    return -1;
  }

  strcpy(ftsr->name, c);

  FT_SLIST_INSERT_HEAD(&ftstat->rpts, ftsr, chain);

  lp->state = PARSE_STATE_REPORT;
  lp->cur_rpt = ftsr;
  lp->cur_rpt_out = (struct ftstat_rpt_out*)0L;

  return 0;

} /* parse_rpt */

/* 
 * function: parse_rpt_type
 *
 * process the 'type' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_type(struct line_parser *lp, struct ftstat *ftstat)
{
  struct typelookup *tl;
  int found;

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }
   
  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting type.", lp->fname, lp->lineno);
    return -1;
  }

  if (lp->cur_rpt->f_new) {
    fterr_warnx("%s line %d: Type previously defined.", lp->fname,
    lp->lineno);
    return -1;
  }

  found = 0;

  for (tl = tlookup; tl->name; ++tl) {

    if (!strcasecmp(lp->word, tl->name)) {

      lp->cur_rpt->allowed_fields = tl->allowed_fields;
      lp->cur_rpt->allowed_options = tl->allowed_options;
      lp->cur_rpt->xfields = tl->xfields;
      lp->cur_rpt->f_new = tl->f_new;
      lp->cur_rpt->f_accum = tl->f_accum;
      lp->cur_rpt->f_calc = tl->f_calc;
      lp->cur_rpt->f_dump = tl->f_dump;
      lp->cur_rpt->f_free = tl->f_free;
      lp->cur_rpt->format_name = tl->name;

      found = 1;

      break;

    }

  } /* for */

  if (!found) {
    fterr_warnx("%s line %d: Unrecognized type.", lp->fname, lp->lineno);
    return -1;
  }

  return 0;

} /* parse_rpt_type */

/* 
 * function: parse_rpt_filter
 *
 * process the 'filter' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_filter(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }
   
  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting filter name.", lp->fname, lp->lineno);
    return -1;
  }

  if (lp->cur_rpt->ftfd) {
    fterr_warnx("%s line %d: Filter previously defined for report .",
    lp->fname, lp->lineno);
    return -1;
  }

  /* delay loading the filters until one is requested */
  if (load_filters(ftstat)) {
    fterr_warnx("%s line %d: Filters not loaded.", lp->fname, lp->lineno);
    return -1;
  }

  if (!(lp->cur_rpt->ftfd = ftfil_def_find(&ftstat->ftfil,
    lp->word))) {
    fterr_warnx("%s line %d: Filter definition not found.", lp->fname,
    lp->lineno);
    return -1;
  }

  return 0;

} /* parse_rpt_filter */

/* 
 * function: parse_rpt_tag_mask
 *
 * process the 'output' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_tag_mask(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting source mask.", lp->fname,
    lp->lineno);
    return -1;
  }

  lp->cur_rpt->tag_mask_src = strtoul(lp->word, (char**)0L, 0);

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting destination mask.", lp->fname,
    lp->lineno);
    return -1;
  }

  lp->cur_rpt->tag_mask_dst = strtoul(lp->word, (char**)0L, 0);

  lp->cur_rpt->options |= FT_STAT_OPT_TAG_MASK;
  lp->cur_rpt->xfields |= FT_XFIELD_SRC_TAG|FT_XFIELD_DST_TAG;

  return 0;

} /* parse_rpt_tag_mask */


/* 
 * function: parse_rpt_scale
 *
 * process the 'scale' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_scale(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting scaling factor.", lp->fname,
    lp->lineno);
    return -1;
  }

  lp->cur_rpt->scale = atoi(lp->word);

  return 0;

} /* parse_rpt_scale */

/* 
 * function: parse_rpt_ip_src_addr_fmt
 *
 * process the 'ip-source-address-format' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_ip_src_addr_fmt(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Not in report.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting address format.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (!(strcasecmp(lp->word, "prefix-len")))
    lp->cur_rpt->options |= FT_STAT_OPT_SRC_PREFIX_LEN;
  else if (!(strcasecmp(lp->word, "prefix-mask")))
    lp->cur_rpt->options |= FT_STAT_OPT_SRC_PREFIX_MASK;
  else if (!(strcasecmp(lp->word, "address")))
    lp->cur_rpt->options &=
      ~(FT_STAT_OPT_SRC_PREFIX_MASK|FT_STAT_OPT_SRC_PREFIX_LEN);
  else {
    fterr_warnx("%s line %d: Invalid address format.", lp->fname, lp->lineno);
    return -1;
  }

  /*
   * if the PREFIX_LEN or PREFIX_MASK option is set then this report
   *  requires the FT_XFIELD_XXX_MASK bits.
   */

  if (lp->cur_rpt->options &
    (FT_STAT_OPT_SRC_PREFIX_MASK|FT_STAT_OPT_SRC_PREFIX_LEN)) {

    if (lp->cur_rpt->xfields & FT_XFIELD_SRCADDR)
      lp->cur_rpt->xfields |= FT_XFIELD_SRC_MASK;

  } else {

    lp->cur_rpt->xfields &= ~ FT_XFIELD_SRC_MASK;

  } /* OPT_PREFIX_* */

  return 0;

} /* parse_rpt_ip_src_addr_fmt */

/* 
 * function: parse_rpt_ip_dst_addr_fmt
 *
 * process the 'ip-address-format' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_ip_dst_addr_fmt(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Not in report.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting address format.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (!(strcasecmp(lp->word, "prefix-len")))
    lp->cur_rpt->options |= FT_STAT_OPT_DST_PREFIX_LEN;
  else if (!(strcasecmp(lp->word, "prefix-mask")))
    lp->cur_rpt->options |= FT_STAT_OPT_DST_PREFIX_MASK;
  else if (!(strcasecmp(lp->word, "address")))
    lp->cur_rpt->options
      &= ~(FT_STAT_OPT_DST_PREFIX_MASK|FT_STAT_OPT_DST_PREFIX_LEN);
  else {
    fterr_warnx("%s line %d: Invalid address format.", lp->fname, lp->lineno);
    return -1;
  }

  /*
   * if the PREFIX_LEN or PREFIX_MASK option is set then this report
   *  requires the FT_XFIELD_XXX_MASK bits.
   */

  if (lp->cur_rpt->options &
    (FT_STAT_OPT_DST_PREFIX_MASK|FT_STAT_OPT_DST_PREFIX_LEN)) {

    if (lp->cur_rpt->xfields & FT_XFIELD_DSTADDR)
      lp->cur_rpt->xfields |= FT_XFIELD_DST_MASK;

  } else {

    lp->cur_rpt->xfields &= ~ FT_XFIELD_DST_MASK;

  } /* OPT_PREFIX_* */

  return 0;

} /* parse_rpt_ip_dst_addr_fmt */

/*
 *************************************************************************
                        parse_rpt_output and friends
 *************************************************************************
 */

/* 
 * function: parse_rpt_output
 *
 * process the 'output' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_output(struct line_parser *lp, struct ftstat *ftstat)
{
  struct ftstat_rpt_out *ftsro;

  if (!lp->cur_rpt) {
    fterr_warnx("%s line %d: Not in a report.", lp->fname, lp->lineno);
    return -1;
  }

  /* add a new entry to the list */
  if (!(ftsro = (struct ftstat_rpt_out*)malloc(sizeof *ftsro))) {
    fterr_warn("malloc()");
    return -1;
  }

  bzero(ftsro, sizeof *ftsro);
  ftsro->f_dump = lp->cur_rpt->f_dump;
  ftsro->fields = lp->cur_rpt->allowed_fields;
  ftsro->fields &= ~(FT_STAT_FIELD_FRECS|
                     FT_STAT_FIELD_INDEX|
                     FT_STAT_FIELD_FIRST|
                     FT_STAT_FIELD_LAST|
                     FT_STAT_FIELD_PPS|
                     FT_STAT_FIELD_BPS); /* default some off */
  ftsro->time = FT_STAT_TIME_MID;
  lp->cur_rpt_out = ftsro;

  FT_STAILQ_INSERT_TAIL(&lp->cur_rpt->outs, ftsro, chain);

  return 0;

} /* parse_rpt_output */

/* 
 * function: parse_rpt_out_format
 *
 * process the 'format' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_format(struct line_parser *lp, struct ftstat *ftstat)
{
  enum ftstat_rpt_format format;

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting format.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (!(strcasecmp(lp->word, "ascii")))
    format = FT_STAT_FMT_ASCII;
  else if (!(strcasecmp(lp->word, "binary")))
    format = FT_STAT_FMT_BINARY;
  else {
    fterr_warnx("%s line %d: Unrecognized format.", lp->fname, lp->lineno);
    return -1;
  }

  lp->cur_rpt->format = format;

  return 0;

} /* parse_rpt_out_format */

/* 
 * function: parse_rpt_out_sort
 *
 * process the 'sort' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_sort(struct line_parser *lp, struct ftstat *ftstat)
{
  int sort_field, sort_order;
  char *c;

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting sort field.", lp->fname,
    lp->lineno);
    return -1;
  }

  c = lp->word;

  if (*c == '+')
    sort_order = FT_STAT_SORT_ASCEND;
  else if (*c == '-')
    sort_order = FT_STAT_SORT_DESCEND;
  else {
    fterr_warnx("%s line %d: Expecting + or -.", lp->fname, lp->lineno);
    return -1;
  }

  ++c;

  if (!(strcasecmp(c, "key")))
    sort_field = FT_STAT_FIELD_KEY;
  else if (!(strcasecmp(c, "key1")))
    sort_field = FT_STAT_FIELD_KEY1;
  else if (!(strcasecmp(c, "key2")))
    sort_field = FT_STAT_FIELD_KEY2;
  else if (!(strcasecmp(c, "key3")))
    sort_field = FT_STAT_FIELD_KEY3;
  else if (!(strcasecmp(c, "key4")))
    sort_field = FT_STAT_FIELD_KEY4;
  else if (!(strcasecmp(c, "key5")))
    sort_field = FT_STAT_FIELD_KEY5;
  else if (!(strcasecmp(c, "key6")))
    sort_field = FT_STAT_FIELD_KEY6;
  else if (!(strcasecmp(c, "flows")))
    sort_field = FT_STAT_FIELD_FLOWS;
  else if (!(strcasecmp(c, "octets")))
    sort_field = FT_STAT_FIELD_OCTETS;
  else if (!(strcasecmp(c, "packets")))
    sort_field = FT_STAT_FIELD_PACKETS;
  else if (!(strcasecmp(c, "duration")))
    sort_field = FT_STAT_FIELD_DURATION;
  else if (!(strcasecmp(c, "avg-pps")))
    sort_field = FT_STAT_FIELD_AVG_PPS;
  else if (!(strcasecmp(c, "min-pps")))
    sort_field = FT_STAT_FIELD_MIN_PPS;
  else if (!(strcasecmp(c, "max-pps")))
    sort_field = FT_STAT_FIELD_MAX_PPS;
  else if (!(strcasecmp(c, "avg-bps")))
    sort_field = FT_STAT_FIELD_AVG_BPS;
  else if (!(strcasecmp(c, "min-bps")))
    sort_field = FT_STAT_FIELD_MIN_BPS;
  else if (!(strcasecmp(c, "max-bps")))
    sort_field = FT_STAT_FIELD_MAX_BPS;
  else if (!(strcasecmp(c, "other")))
    sort_field = FT_STAT_FIELD_OTHER;
  else if (!(strcasecmp(c, "count")))
    sort_field = FT_STAT_FIELD_COUNT;
  else if (!(strcasecmp(c, "")))
    sort_field = 0;
  else {
    fterr_warnx("%s line %d: Unrecognized field.", lp->fname, lp->lineno);
    return -1;
  }

  if (sort_field) {

    /* make sure that the field selected is valid for this report type */
    if ((lp->cur_rpt->allowed_fields & sort_field) != sort_field) {
      fterr_warnx("%s line %d: field \"%s\" selected not available for report.",
        lp->fname, lp->lineno, c);
      return -1;
    }

    lp->cur_rpt_out->sort_field = sort_field;
    lp->cur_rpt_out->sort_order = sort_order;
    lp->cur_rpt_out->options |= FT_STAT_OPT_SORT;

  }

  return 0;

} /* parse_rpt_out_sort */

/* 
 * function: parse_rpt_out_records
 *
 * process the 'records' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_records(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting num records.", lp->fname,
    lp->lineno);
    return -1;
  }

  lp->cur_rpt_out->records = strtoull(lp->word, (char**)0L, 0);

  return 0;

} /* parse_rpt_out_records */

/* 
 * function: parse_rpt_out_tally
 *
 * process the 'tally' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_tally(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting tally increment.", lp->fname,
    lp->lineno);
    return -1;
  }

  lp->cur_rpt_out->tally = strtoul(lp->word, (char**)0L, 0);

  if (lp->cur_rpt_out->tally)
    lp->cur_rpt_out->options |= FT_STAT_OPT_TALLY;
  else
    lp->cur_rpt_out->options &= ~FT_STAT_OPT_TALLY;

  return 0;

} /* parse_rpt_out_tally */

/* 
 * function: parse_rpt_out_fields
 *
 * process the 'fields' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_fields(struct line_parser *lp, struct ftstat *ftstat)
{
  char *c, op;
  u_int32 nfields;

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  if (!lp->buf) {
    fterr_warnx("%s line %d: Expecting display fields.", lp->fname,
    lp->lineno);
    return -1;
  }

  c = lp->buf;

  while (c) {

    for (;;) {
      c = strsep(&lp->buf, " ,");
      if ((c && *c) || (!c))
        break;
    }

    if (!c)
      break;

    /* + to select, - to remove */
    op = *c++;

    if ((op != '+') && (op != '-')) {
      fterr_warnx("%s line %d: Expecting +field or -field.", lp->fname,
        lp->lineno);
      return -1;
    }

    nfields = 0;

    if (!(strcasecmp(c, "index")))
      nfields |= FT_STAT_FIELD_INDEX;
    else if (!(strcasecmp(c, "first")))
      nfields |= FT_STAT_FIELD_FIRST;
    else if (!(strcasecmp(c, "last")))
      nfields |= FT_STAT_FIELD_LAST;
    else if (!(strcasecmp(c, "key")))
      nfields |= FT_STAT_FIELD_KEY;
    else if (!(strcasecmp(c, "key1")))
      nfields |= FT_STAT_FIELD_KEY1;
    else if (!(strcasecmp(c, "key2")))
      nfields |= FT_STAT_FIELD_KEY2;
    else if (!(strcasecmp(c, "key3")))
      nfields |= FT_STAT_FIELD_KEY3;
    else if (!(strcasecmp(c, "key4")))
      nfields |= FT_STAT_FIELD_KEY4;
    else if (!(strcasecmp(c, "key5")))
      nfields |= FT_STAT_FIELD_KEY5;
    else if (!(strcasecmp(c, "key6")))
      nfields |= FT_STAT_FIELD_KEY6;
    else if (!(strcasecmp(c, "flows")))
      nfields |= FT_STAT_FIELD_FLOWS;
    else if (!(strcasecmp(c, "octets")))
      nfields |= FT_STAT_FIELD_OCTETS;
    else if (!(strcasecmp(c, "packets")))
      nfields |= FT_STAT_FIELD_PACKETS;
    else if (!(strcasecmp(c, "duration")))
      nfields |= FT_STAT_FIELD_DURATION;
    else if (!(strcasecmp(c, "pps")))
      nfields |= FT_STAT_FIELD_PPS;
    else if (!(strcasecmp(c, "avg-pps")))
      nfields |= FT_STAT_FIELD_AVG_PPS;
    else if (!(strcasecmp(c, "min-pps")))
      nfields |= FT_STAT_FIELD_MIN_PPS;
    else if (!(strcasecmp(c, "max-pps")))
      nfields |= FT_STAT_FIELD_MAX_PPS;
    else if (!(strcasecmp(c, "bps")))
      nfields |= FT_STAT_FIELD_BPS;
    else if (!(strcasecmp(c, "avg-bps")))
      nfields |= FT_STAT_FIELD_AVG_BPS;
    else if (!(strcasecmp(c, "min-bps")))
      nfields |= FT_STAT_FIELD_MIN_BPS;
    else if (!(strcasecmp(c, "max-bps")))
      nfields |= FT_STAT_FIELD_MAX_BPS;
    else if (!(strcasecmp(c, "other")))
      nfields |= FT_STAT_FIELD_OTHER;
    else if (!(strcasecmp(c, "generic")))
      nfields |= FT_STAT_FIELD_GENERIC;
    else if (!(strcasecmp(c, "count")))
      nfields |= FT_STAT_FIELD_COUNT;
    else if (!(strcasecmp(c, "frecs")))
      nfields |= FT_STAT_FIELD_FRECS;
    else if (!(strcasecmp(c, "")))
      nfields |= 0;
    else {
      fterr_warnx("%s line %d: Unrecognized field.", lp->fname, lp->lineno);
      return -1;
    }

    /* make sure that the field is valid for this report type */

    if ((lp->cur_rpt->allowed_fields & nfields) != nfields) {
      fterr_warnx(
        "%s line %d: field \"%s\" selected not available for report.",
        lp->fname, lp->lineno, c);
      return -1;
    }

    if (op == '+')
      lp->cur_rpt_out->fields |= nfields;
    else if (op == '-')
      lp->cur_rpt_out->fields &= ~nfields;

    nfields = 0;

  } /* c */

  return 0;

} /* parse_rpt_out_fields */

/* 
 * function: parse_rpt_out_options
 *
 * process the 'options' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_options(struct line_parser *lp, struct ftstat *ftstat)
{
  int options;
  char *c, op;

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  if (!lp->buf) {
    fterr_warnx("%s line %d: Expecting options.", lp->fname,
    lp->lineno);
    return -1;
  }

  c = lp->buf;

  while (c) {

    for (;;) {
      c = strsep(&lp->buf, " ,");
      if ((c && *c) || (!c))
        break;
    }

    if (!c)
      break;

    /* + to select, - to remove */
    op = *c++;

    if ((op != '+') && (op != '-')) {
      fterr_warnx("%s line %d: Expecting +option or -option.", lp->fname,
        lp->lineno);
      return -1;
    }

    options = 0;

    if (!(strcasecmp(c, "percent-total")))
      options |= FT_STAT_OPT_PERCENT;
    else if (!(strcasecmp(c, "names")))
      options |= FT_STAT_OPT_NAMES;
    else if (!(strcasecmp(c, "header")))
      options |= FT_STAT_OPT_HEADER;
    else if (!(strcasecmp(c, "xheader")))
      options |= FT_STAT_OPT_XHEADER;
    else if (!(strcasecmp(c, "totals")))
      options |= FT_STAT_OPT_TOTALS;
    else {
      fterr_warnx("%s line %d: Unrecognized option.", lp->fname, lp->lineno);
      return -1;
    }

    /* make sure that the option is valid for this report type */

    if ((lp->cur_rpt->allowed_options & options) != options) {
      fterr_warnx("%s line %d: option selected not available for report.",
        lp->fname, lp->lineno);
      return -1;
    }

    if (op == '+') 
      lp->cur_rpt_out->options |= options;
    else if (op == '-')
      lp->cur_rpt_out->options &= ~options;

    options = 0;

  } /* c */

  return 0;

} /* parse_rpt_out_options */

/* 
 * function: parse_rpt_out_path
 *
 * process the 'path' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_path(struct line_parser *lp, struct ftstat *ftstat)
{
  char *c;
  int len;

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  if (!lp->buf) {
    fterr_warnx("%s line %d: Expecting pathname.", lp->fname, lp->lineno);
    return -1;
  }

  len = strlen(lp->buf);

  if (!(c = malloc(len+1))) {
    fterr_warn("malloc()");
    return -1;
  }

  strcpy(c, lp->buf);

  lp->cur_rpt_out->path = c;

  /* eat the line */
  for (; *(lp->buf); ++lp->buf);

  return 0;

} /* parse_rpt_out_path */

/* 
 * function: parse_rpt_out_time
 *
 * process the 'time' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_rpt_out_time(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_rpt_out) {
    fterr_warnx("%s line %d: Not in report output.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting time specifier.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (!(strcasecmp(lp->word, "now")))
    lp->cur_rpt_out->time = FT_STAT_TIME_NOW;
  else if (!(strcasecmp(lp->word, "start")))
    lp->cur_rpt_out->time = FT_STAT_TIME_START;
  else if (!(strcasecmp(lp->word, "end")))
    lp->cur_rpt_out->time = FT_STAT_TIME_END;
  else if (!(strcasecmp(lp->word, "mid")))
    lp->cur_rpt_out->time = FT_STAT_TIME_MID;
  else {
    fterr_warnx("%s line %d: Invalid time specifier.", lp->fname, lp->lineno);
    return -1;
  }

  return 0;

} /* parse_rpt_out_time */

/*
 *************************************************************************
                             parse_def_* 
 *************************************************************************
 */

/* 
 * function: parse_def
 *
 * process the 'stat-definition' line.  Each definition has a unique name
 * which is added to the ftstat->defs linked list.  The current
 * definition is updated in lp.  Definitions reference reports
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_def(struct line_parser *lp, struct ftstat *ftstat)
{
  char *c;
  struct ftstat_def *ftsd;
   
  NEXT_WORD(&lp->buf, c);
  
  if (!c) {
    fterr_warnx("%s line %d: Expecting name.", lp->fname, lp->lineno);
    return -1;
  }

  /* check if it exists */
  FT_SLIST_FOREACH(ftsd, &ftstat->defs, chain) {

    if (!strcasecmp(c, ftsd->name)) {
      fterr_warnx("%s line %d: Name (%s) previously defined.", lp->fname,
        lp->lineno, c);
      return -1;
    }

  }

  /* no, add a new entry to the list */
  if (!(ftsd = (struct ftstat_def*)malloc(sizeof *ftsd))) {
    fterr_warn("malloc()");
    return -1;
  }

  bzero(ftsd, sizeof *ftsd);
  FT_STAILQ_INIT(&ftsd->items);

  if (!(ftsd->name = (char*)malloc(strlen(c)+1))) {
    fterr_warn("malloc()");
    free(ftsd);
    return -1;
  }

  strcpy(ftsd->name, c);
  ftsd->ftstat = ftstat;

  FT_SLIST_INSERT_HEAD(&ftstat->defs, ftsd, chain);

  lp->state = PARSE_STATE_DEFINITION;
  lp->cur_def = ftsd;

  return 0;

} /* parse_def */

/* 
 * function: parse_def_filter
 *
 * process the 'filter' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_def_filter(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_def) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting filter name.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (lp->cur_def->ftfd) {
    fterr_warnx("%s line %d: Filter previously defined for definition.",
    lp->fname, lp->lineno);
    return -1;
  }

  /* delay loading the filters until one is requested */
  if (load_filters(ftstat)) {
    fterr_warnx("%s line %d: Filters not loaded.", lp->fname, lp->lineno);
    return -1;
  }

  if (!(lp->cur_def->ftfd = ftfil_def_find(&ftstat->ftfil,
    lp->word))) {
    fterr_warnx("%s line %d: Filter definition not found.", lp->fname,
    lp->lineno);
    return -1;
  }

  return 0;

} /* parse_def_filter */

/* 
 * function: parse_def_tag
 *
 * process the 'tag' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_def_tag(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_def) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting tag name.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (lp->cur_def->ftd) {
    fterr_warnx("%s line %d: Tag previously defined for definition.",
    lp->fname, lp->lineno);
    return -1;
  }

  /* delay loading the tags until one is requested */
  if (load_tags(ftstat)) {
    fterr_warnx("%s line %d: Tags not loaded.", lp->fname, lp->lineno);
    return -1;
  }

  if (!(lp->cur_def->ftd = fttag_def_find(&ftstat->fttag, lp->word))) {
    fterr_warnx("%s line %d: Tag definition not found.", lp->fname,
    lp->lineno);
    return -1;
  }

  return 0;

} /* parse_def_tag */

/* 
 * function: parse_def_mask
 *
 * process the 'mask' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_def_mask(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_def) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting mask name.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (lp->cur_def->ftd) {
    fterr_warnx("%s line %d: Mask previously defined for definition.",
    lp->fname, lp->lineno);
    return -1;
  }

  /* delay loading the tags until one is requested */
  if (load_masks(ftstat)) {
    fterr_warnx("%s line %d: Masks not loaded.", lp->fname, lp->lineno);
    return -1;
  }

  if (!(lp->cur_def->ftmd = ftmask_def_find(&ftstat->ftmask, lp->word))) {
    fterr_warnx("%s line %d: Mask definition not found.", lp->fname,
    lp->lineno);
    return -1;
  }

  return 0;

} /* parse_def_mask */

/* 
 * function: parse_def_time_series
 *
 * process the 'time-series' line.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_def_time_series(struct line_parser *lp, struct ftstat *ftstat)
{

  if (!lp->cur_def) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting time in seconds.", lp->fname,
    lp->lineno);
    return -1;
  }

  if (lp->cur_def->max_time) {
    fterr_warnx("%s line %d: Time previously defined for definition.",
    lp->fname, lp->lineno);
    return -1;
  }

  lp->cur_def->max_time = strtoul(lp->word, (char**)0L, 0);
  lp->cur_def->xfields |= FT_XFIELD_UNIX_SECS;

  return 0;

} /* parse_def_time_series */


/* 
 * function: parse_def_report
 *
 * process the 'report' line.
 *
 * resolve_reports() _must_ be called after the configuration file has
 * been parsed and before the parse buffer is released.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_def_report(struct line_parser *lp, struct ftstat *ftstat)
{
  struct ftstat_rpt_item *ftsrpti;
  int n;

  if (!lp->cur_def) {
    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
    return -1;
  }

  NEXT_WORD(&lp->buf, lp->word);

  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting report name.", lp->fname,
    lp->lineno);
    return -1;
  }

  /* make sure this report is only added once */
  FT_STAILQ_FOREACH(ftsrpti, &lp->cur_def->items, chain) {

    if (!(strcasecmp(lp->word, ftsrpti->tmp_report))) {
      fterr_warnx("%s line %d: Duplicate report in definition.", lp->fname,
        lp->lineno);
      return -1;
    }

  }

  /* add this report to the list */
  if (!(ftsrpti = (struct ftstat_rpt_item*)malloc (sizeof *ftsrpti))) {
    fterr_warn("malloc()");
    return -1;
  }

  bzero(ftsrpti, sizeof *ftsrpti);

  /* resolve this later in resolve_reports(); */
  n = strlen(lp->word);
  if (!(ftsrpti->tmp_report = malloc(n+1)))
    fterr_errx(1, "malloc(tmp_report): failed");
  strcpy(ftsrpti->tmp_report, lp->word);

  FT_STAILQ_INSERT_TAIL(&lp->cur_def->items, ftsrpti, chain);

  return 0;

} /* parse_def_report */


/* 
 * function: parse_include_tag
 *
 * process the 'include-tag' line.  Allow the default tag location
 * to be changed.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_include_tag(struct line_parser *lp, struct ftstat *ftstat)
{

  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting pathname.", lp->fname, lp->lineno);
    return -1;
  }

  if (ftstat->tag_fname) {
    fterr_warnx("%s line %d: Tag pathname previously specified.",
    lp->fname, lp->lineno);
    return -1;
  }

  if (!(ftstat->tag_fname = malloc(strlen(lp->word)+1)))
    fterr_errx(1, "malloc(tag_fname): failed");
  strcpy(ftstat->tag_fname, lp->word);

  return 0;

} /* parse_include_tag */

/* 
 * function: parse_include_filter
 *
 * process the 'include-filter' line.  Allow the default filter location
 * to be changed.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_include_filter(struct line_parser *lp, struct ftstat *ftstat)
{

  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting pathname.", lp->fname, lp->lineno);
    return -1;
  }

  if (ftstat->filter_fname) {
    fterr_warnx("%s line %d: Filter pathname previously specified.",
    lp->fname, lp->lineno);
    return -1;
  }

  if (!(ftstat->filter_fname = malloc(strlen(lp->word)+1)))
    fterr_errx(1, "malloc(filter_fname): failed");
  strcpy(ftstat->filter_fname, lp->word);

  return 0;

} /* parse_include_filter */

/* 
 * function: parse_include_mask
 *
 * process the 'include-mask' line.  Allow the default mask location
 * to be changed.
 *
 * returns: 0  ok
 *          <0 fail
 */
int parse_include_mask(struct line_parser *lp, struct ftstat *ftstat)
{

  NEXT_WORD(&lp->buf, lp->word);
  
  if (!lp->word) {
    fterr_warnx("%s line %d: Expecting pathname.", lp->fname, lp->lineno);
    return -1;
  }

  if (ftstat->mask_fname) {
    fterr_warnx("%s line %d: Mask pathname previously specified.",
    lp->fname, lp->lineno);
    return -1;
  }

  if (!(ftstat->mask_fname = malloc(strlen(lp->word)+1)))
    fterr_errx(1, "malloc(mask_fname): failed");
  strcpy(ftstat->mask_fname, lp->word);

  return 0;

} /* parse_include_mask */

/*
 *************************************************************************
                     ftstat_rpt_*_new/free/accum/dump 
 *************************************************************************
 */


/* function: ftstat_rpt_1_new
 *
 * Allocate and initialize data structures for rpt 1.
 *
 * returns allocated struct or 0L for error
 */
struct ftstat_rpt_1 *ftstat_rpt_1_new(struct ftstat_rpt *rpt)
{
  struct ftstat_rpt_1 *rpt1;

  if (!(rpt1 = (struct ftstat_rpt_1*)malloc(sizeof (*rpt1)))) {
    fterr_warnx("malloc(rpt1): failed");
    return (struct ftstat_rpt_1*)0L;
  }

  bzero(rpt1, sizeof *rpt1);

  return rpt1;

} /* ftstat_rpt_1_new */


/* function: ftstat_rpt_1_accum
 *
 * Accumulate counters for report by processing flow.
 *
 * returns 0: ok
 *        !0: error
 */
int ftstat_rpt_1_accum(struct ftstat_rpt *rpt, char *rec,
  struct fts3rec_offsets *fo)
{
  struct ftstat_rpt_1 *rpt1;
  struct fts3rec_all2 cur;
  u_int32 time_tmp, duration_tmp;
  double pps_tmp, bps_tmp;
  u_long p;

  STD_ACCUM;

  rpt1 = rpt->data;

  time_tmp = cur.unix_secs;
  
  if (time_tmp < rpt1->time_start)
    rpt1->time_start = time_tmp;
  
  if (time_tmp > rpt1->time_end)
    rpt1->time_end = time_tmp;

  if (cur.First < rpt1->start)
    rpt1->start = cur.First;
  
  if (cur.Last > rpt1->end)
    rpt1->end = cur.Last;

  p = cur.dOctets64 / cur.dPkts64;

  if (p <= 32) ++ rpt1->psize32;
  else if (p <= 64) ++ rpt1->psize64;
  else if (p <= 96) ++ rpt1->psize96;
  else if (p <= 128) ++ rpt1->psize128;
  else if (p <= 160) ++ rpt1->psize160;
  else if (p <= 192) ++ rpt1->psize192;
  else if (p <= 224) ++ rpt1->psize224;
  else if (p <= 256) ++ rpt1->psize256;
  else if (p <= 288) ++ rpt1->psize288;
  else if (p <= 320) ++ rpt1->psize320;
  else if (p <= 352) ++ rpt1->psize352;
  else if (p <= 384) ++ rpt1->psize384;
  else if (p <= 416) ++ rpt1->psize416;
  else if (p <= 448) ++ rpt1->psize448;
  else if (p <= 480) ++ rpt1->psize480;
  else if (p <= 512) ++ rpt1->psize512;
  else if (p <= 544) ++ rpt1->psize544;
  else if (p <= 576) ++ rpt1->psize576;
  else if (p <= 1024) ++ rpt1->psize1024;
  else if (p <= 1536) ++ rpt1->psize1536;
  else if (p <= 2048) ++ rpt1->psize2048;
  else if (p <= 2560) ++ rpt1->psize2560;
  else if (p <= 3072) ++ rpt1->psize3072;
  else if (p <= 3584) ++ rpt1->psize3584;
  else if (p <= 4096) ++ rpt1->psize4096;
  else if (p <= 4608) ++ rpt1->psize4608;

  p = cur.dPkts64;

  if (p <= 1) ++ rpt1->fpsize1;
  else if (p <= 2) ++ rpt1->fpsize2;
  else if (p <= 4) ++ rpt1->fpsize4;
  else if (p <= 8) ++ rpt1->fpsize8;  
  else if (p <= 12) ++ rpt1->fpsize12;
  else if (p <= 16) ++ rpt1->fpsize16;
  else if (p <= 20) ++ rpt1->fpsize20;
  else if (p <= 24) ++ rpt1->fpsize24;
  else if (p <= 28) ++ rpt1->fpsize28;
  else if (p <= 32) ++ rpt1->fpsize32;
  else if (p <= 36) ++ rpt1->fpsize36;
  else if (p <= 40) ++ rpt1->fpsize40;
  else if (p <= 44) ++ rpt1->fpsize44;
  else if (p <= 48) ++ rpt1->fpsize48;
  else if (p <= 52) ++ rpt1->fpsize52;
  else if (p <= 60) ++ rpt1->fpsize60;
  else if (p <= 100) ++ rpt1->fpsize100;
  else if (p <= 200) ++ rpt1->fpsize200;
  else if (p <= 300) ++ rpt1->fpsize300;
  else if (p <= 400) ++ rpt1->fpsize400;
  else if (p <= 500) ++ rpt1->fpsize500;
  else if (p <= 600) ++ rpt1->fpsize600;
  else if (p <= 700) ++ rpt1->fpsize700;
  else if (p <= 800) ++ rpt1->fpsize800;
  else if (p <= 900) ++ rpt1->fpsize900;
  else ++ rpt1->fpsize_other;

  p = cur.dOctets64;

  if (p <= 32) ++ rpt1->fosize32;
  else if (p <= 64) ++ rpt1->fosize64;
  else if (p <= 128) ++ rpt1->fosize128;
  else if (p <= 256) ++ rpt1->fosize256;
  else if (p <= 512) ++ rpt1->fosize512;
  else if (p <= 1280) ++ rpt1->fosize1280;