/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe is free software; you can redistribute it and/or modify            *
*   it under the terms of the GNU General Public License as published by      *
*   the Free Software Foundation; either version 2 of the License, or         *
*   (at your option) any later version.                                       *
*                                                                             *
*   Nprobe is distributed in the hope that it will be useful,                 *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*   GNU General Public License for more details.                              *
*                                                                             *
*   You should have received a copy of the GNU General Public License         *
*   along with Nprobe; if not, write to the Free Software                     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
*                                                                             *
******************************************************************************/


#include <stdio.h>
#include <sys/param.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#ifdef __alpha__
#include <sys/mbuf.h>
#endif
#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#undef __STDC__
#include <netinet/ip.h>

#ifdef __alpha__
#include <netinet/ip_var.h>
#endif
#include <netinet/tcp.h>
#include <netinet/if_ether.h>

#include <assert.h>

#include "list.h"
#include "pkt.h"
#include "interface.h"
#include "flows.h"
#include "http.h"
#include "tcp.h"
# include "np_file.h"
#include "udp.h"
#include "service.h"
#include "tcp_other.h"
#include "udp_other.h"
#include "udp_ns.h"
#include "timeouts.h"
#include "seq.h"

#undef __ia64__
#include "counters.h"
#include "writer.h"
#include "if_nprobe.h"

#ifdef PRINT_OUT
#include "print_util.h"
#endif

#include "output.h"
#include "pool.h"

#define TELL_SZ(obj)  \
MACRO_BEGIN    \
  printf("\t%18s %6d\n", #obj, sizeof(obj)); \
MACRO_END

#define USE_SZ(obj, n)  \
MACRO_BEGIN    \
  int used = n*sizeof(obj); \
  printf("\t%18s *%8d =%10d\n", #obj, n, used); \
  tot_use += used; \
MACRO_END

#define TELL_OFFSET(cont, field, what)  \
MACRO_BEGIN    \
  printf("%10s %6d at %5d\n", #field, sizeof(what), (char *)&cont.field - (char *)&cont); \
MACRO_END
  

void offsets()
{
  counters_t ct;
  flow_inner_t ft;
  tcp_simplex_flow_t tsf;
  ns_rec_t nsr;

  printf("\n\nOffsets:-\n\n");
  
  printf("Counters:\n");
  TELL_OFFSET(ct, fh, fhdr_t);
  TELL_OFFSET(ct, start, tmval);
  TELL_OFFSET(ct, max_ctrs, max_ctrs_t);
  TELL_OFFSET(ct, run_ctrs, run_ctrs_t);

  printf("Flow_inner:\n");
  TELL_OFFSET(ft, serv_type, unsigned char);

  printf("TCP simplex:\n");
  TELL_OFFSET(tsf, nheld, unsigned char);
  TELL_OFFSET(tsf, mss, unsigned short);
  TELL_OFFSET(tsf, wshift, unsigned char);

  printf("Ns rec:\n");
  TELL_OFFSET(nsr, req_us, unsigned int);
  TELL_OFFSET(nsr, rep_us, unsigned int);
  TELL_OFFSET(nsr, state, unsigned short);
  TELL_OFFSET(nsr, id, unsigned short);
  TELL_OFFSET(nsr, ns_parms, ns_parms_t);
  TELL_OFFSET(nsr, buflen, int);
  

  return;
  
}


int 
main()
{
  int tot_use = 0;
  int tmp_use = 0;
  printf("Sizes:-\n");

  TELL_SZ(host_flow_t);
  TELL_SZ(tcp_conn_t);
  TELL_SZ(tcp_hdrs_t);
  TELL_SZ(http_trans_t);
  TELL_SZ(udp_conn_t);
  TELL_SZ(prec_t);
  TELL_SZ(tcp_heldpkt_t);
  TELL_SZ(hdr_buf_t);
  TELL_SZ(links_buf_t);
  TELL_SZ(ns_q_t);

  TELL_SZ(http_transinf_t);
  TELL_SZ(http_trans_both_t);
  TELL_SZ(http_trans_inner_t);

  TELL_SZ(counters_t);
  printf("\t%18s %6d\n", "host_hashtbl", N_HOST_BUCKETS * sizeof(listhdr_t));

  TELL_SZ(nprobe_hdr_t);

  printf("TCP part max write size = %d\n", TCP_PART_MAXWRITESZ);
  printf("HTTP trans max write size = %d\n", TRANS_MAX_WRITESZ);

  printf("Output buffer overrun should be: ");
  printf("%d buffers of %d kB\n", 
	 (MAX_WRITESZ/WRITE_BLKSZ) + 1, WRITE_BLKSZ/1024);

  printf("Total memory usage:-\n");
  printf("\tPools:\n");
  USE_SZ(host_flow_t, HOSTFLOW_POOL_SZ);
  USE_SZ(tcp_conn_t, TCONN_POOL_SZ);
  USE_SZ(udp_conn_t, UCONN_POOL_SZ);
  USE_SZ(http_trans_t, TRANS_POOL_SZ);
  USE_SZ(tcp_heldpkt_t, HELDPKT_POOL_SZ);
  USE_SZ(prec_t, PREC_POOL_SZ);
  USE_SZ(hdr_buf_t, HDR_BUF_POOL_SZ);
  USE_SZ(links_buf_t, LINKS_POOL_SZ);
  USE_SZ(ns_q_t, NS_REC_POOL_SZ);
  printf("\t\t%45d\n", tot_use);

  printf("\tOutput buffers:\n");
  printf("\t\t%10s%22d\n", "Report", (N_REPBLKS+N_REP_ORUNBLKS)*WRITE_BLKSZ);
  printf("\t\t%10s%22d\n", "DUMP", (N_DUMPBLKS+N_DUMP_ORUNBLKS)*WRITE_BLKSZ);
  printf("\t\t%45d\n", (N_REPBLKS+N_REP_ORUNBLKS)*WRITE_BLKSZ
	 + (N_DUMPBLKS+N_DUMP_ORUNBLKS)*WRITE_BLKSZ);

  tot_use +=  (N_REPBLKS+N_REP_ORUNBLKS)*WRITE_BLKSZ
	 + (N_DUMPBLKS+N_DUMP_ORUNBLKS)*WRITE_BLKSZ;

  printf("\t%10s%39d\n", "Host hashtable", N_HOST_BUCKETS * sizeof(listhdr_t));
  tot_use += N_HOST_BUCKETS * sizeof(listhdr_t);

  printf("\n");
  
  printf("\t\t%25s%20d\n", "Total data space", tot_use);
  
  printf("\n");
  printf("Maximum rep write size = %d\n", MAX_WRITESZ);
  
  printf("\n");
  printf("\n");
  printf("Other sizes:-\n");
  TELL_SZ(fhdr_t);
  TELL_SZ(ctr_t);
  TELL_SZ(max_ctr_t);
  TELL_SZ(max_ctrs_t);
  TELL_SZ(run_ctrs_t);
  TELL_SZ(counters_t);
  TELL_SZ(struct timeval);
  TELL_SZ(flow_inner_t);
  TELL_SZ(tcp_open_t);
  TELL_SZ(tcp_dumphdr_t);
  TELL_SZ(tcp_hdrs_t);
  TELL_SZ(tcp_simplex_flow_t);
  TELL_SZ(http_conn_meta_t);
  TELL_SZ(http_transinf_t);
  TELL_SZ(http_trans_cinf_t);
  TELL_SZ(http_trans_sinf_t);
  TELL_SZ(udp_simplex_flow_t);
  TELL_SZ(ns_rec_t);
  offsets();

  return 0;
}
