/*  stat_ntoh.c is part of Statnet */
/* Statnet is protected under the GNU Public License (GPL2). */
/* Author: Jeroen Baekelandt (jeroenb@igwe.vub.ac.be)        */
/* 13MAR98: Scot E. Wilcoxon (sewilco@fieldday.mn.org)       */


#include "stat.h"
#include <stdio.h>
#include <values.h>
  
/* Copy a pointer which is relative to the start of a block of memory */
#define PtrCpy(A,B,AP,BP) AP=(void *)((A)+(((void *)BP)-((void *)B)));

void
stat_ntoh ( struct StatMemStruct *New, 
	struct StatMemStruct *Prev ) 
{
  unsigned	byteorder, temp_int, search;

  byteorder = 0;
  if( Prev->statmem_label == (unsigned long int)STAT_MAGIC )
	  byteorder = 1;	/* Don't have to do any conversion */
  else
	if( ntohl( Prev->statmem_label ) == (unsigned long int)STAT_MAGIC )
		byteorder = 2;	/* Have to use ntohl() */
	else
		if( htonl( Prev->statmem_label ) == (unsigned long int)STAT_MAGIC )
			byteorder = 3;	/* Odd, but use htonl() because it works */

  switch( byteorder )
  {  /* switch based on needed conversion */

    default:
    case 0:
    case 1:
      {  /* case 1 */
	  PtrCpy(New, Prev, New->prot.types, Prev->prot.types);
	  PtrCpy(New, Prev, New->prot.t_count, Prev->prot.t_count);

	  /* A few items which are not simple counters */
	  New->regis.unknown_type = Prev->regis.unknown_type;
	  New->regis.unknown_frame_type = Prev->regis.unknown_frame_type;
	  New->regis.unknown_sap = Prev->regis.unknown_sap;
	  New->regis.errcode = Prev->regis.errcode;

	  New->regis.errcount = ( Prev->regis.errcount );
	  New->regis.ethercount = ( Prev->regis.ethercount );
	  New->regis.etherbytes = ( Prev->regis.etherbytes );
	  New->regis.plipcount = ( Prev->regis.plipcount );
	  New->regis.plipbytes = ( Prev->regis.plipbytes );
	  New->regis.slipcount = ( Prev->regis.slipcount );
	  New->regis.slipbytes = ( Prev->regis.slipbytes );
	  New->regis.pppcount = ( Prev->regis.pppcount );
	  New->regis.pppbytes = ( Prev->regis.pppbytes );
	  New->regis.loopcount = ( Prev->regis.loopcount );
	  New->regis.loopbytes = ( Prev->regis.loopbytes );
	  New->regis.othercount = ( Prev->regis.othercount );
	  New->regis.otherbytes = ( Prev->regis.otherbytes );
	  New->regis.aarp = ( Prev->regis.aarp );
	  New->regis.rtmprd = ( Prev->regis.rtmprd );
	  New->regis.nbp = ( Prev->regis.nbp );
	  New->regis.atp = ( Prev->regis.atp );
	  New->regis.aep = ( Prev->regis.aep );
	  New->regis.rtmpreq = ( Prev->regis.rtmpreq );
	  New->regis.zip = ( Prev->regis.zip );
	  New->regis.adsp = ( Prev->regis.adsp );
	  New->regis.new_ethernet_count = ( Prev->regis.new_ethernet_count );
	  New->regis.unknown_type = ( Prev->regis.unknown_type );
	  break;
      }  /* case 1 */
    case 2:
      {  /* case 2 */
	  PtrCpy(New, Prev, New->prot.types, ntohl( (int)Prev->prot_types) );
	  PtrCpy(New, Prev, New->prot.t_count, ntohl( (int)Prev->prot.t_count) );

	  /* A few items which are not simple counters */
	  New->regis.unknown_type = ntohl( Prev->regis.unknown_type );
	  New->regis.unknown_frame_type = ntohl(Prev->regis.unknown_frame_type);
	  New->regis.unknown_sap = ntohl( Prev->regis.unknown_sap );
	  New->regis.errcode = ntohl( Prev->regis.errcode );

	  New->regis.errcount = ntohl( Prev->regis.errcount );
	  New->regis.ethercount = ntohl( Prev->regis.ethercount );
	  New->regis.etherbytes = ntohl( Prev->regis.etherbytes );
	  New->regis.plipcount = ntohl( Prev->regis.plipcount );
	  New->regis.plipbytes = ntohl( Prev->regis.plipbytes );
	  New->regis.slipcount = ntohl( Prev->regis.slipcount );
	  New->regis.slipbytes = ntohl( Prev->regis.slipbytes );
	  New->regis.pppcount = ntohl( Prev->regis.pppcount );
	  New->regis.pppbytes = ntohl( Prev->regis.pppbytes );
	  New->regis.loopcount = ntohl( Prev->regis.loopcount );
	  New->regis.loopbytes = ntohl( Prev->regis.loopbytes );
	  New->regis.othercount = ntohl( Prev->regis.othercount );
	  New->regis.otherbytes = ntohl( Prev->regis.otherbytes );
	  New->regis.aarp = ntohl( Prev->regis.aarp );
	  New->regis.rtmprd = ntohl( Prev->regis.rtmprd );
	  New->regis.nbp = ntohl( Prev->regis.nbp );
	  New->regis.atp = ntohl( Prev->regis.atp );
	  New->regis.aep = ntohl( Prev->regis.aep );
	  New->regis.rtmpreq = ntohl( Prev->regis.rtmpreq );
	  New->regis.zip = ntohl( Prev->regis.zip );
	  New->regis.adsp = ntohl( Prev->regis.adsp );
	  New->regis.new_ethernet_count = ntohl( Prev->regis.new_ethernet_count );
	  New->regis.unknown_type = ntohl( Prev->regis.unknown_type );
	  break;
      }  /* case 2 */
    case 3:
      {  /* case 3 */
	  PtrCpy(New, Prev, New->prot.types, htonl( (int)Prev->prot_types) );
	  PtrCpy(New, Prev, New->prot.t_count, htonl( (int)Prev->prot.t_count) );

	  /* A few items which are not simple counters */
	  New->regis.unknown_type = htonl( Prev->regis.unknown_type );
	  New->regis.unknown_frame_type = htonl(Prev->regis.unknown_frame_type);
	  New->regis.unknown_sap = htonl( Prev->regis.unknown_sap );
	  New->regis.errcode = htonl( Prev->regis.errcode );

	  New->regis.errcount = htonl( Prev->regis.errcount );
	  New->regis.ethercount = htonl( Prev->regis.ethercount );
	  New->regis.etherbytes = htonl( Prev->regis.etherbytes );
	  New->regis.plipcount = htonl( Prev->regis.plipcount );
	  New->regis.plipbytes = htonl( Prev->regis.plipbytes );
	  New->regis.slipcount = htonl( Prev->regis.slipcount );
	  New->regis.slipbytes = htonl( Prev->regis.slipbytes );
	  New->regis.pppcount = htonl( Prev->regis.pppcount );
	  New->regis.pppbytes = htonl( Prev->regis.pppbytes );
	  New->regis.loopcount = htonl( Prev->regis.loopcount );
	  New->regis.loopbytes = htonl( Prev->regis.loopbytes );
	  New->regis.othercount = htonl( Prev->regis.othercount );
	  New->regis.otherbytes = htonl( Prev->regis.otherbytes );
	  New->regis.aarp = htonl( Prev->regis.aarp );
	  New->regis.rtmprd = htonl( Prev->regis.rtmprd );
	  New->regis.nbp = htonl( Prev->regis.nbp );
	  New->regis.atp = htonl( Prev->regis.atp );
	  New->regis.aep = htonl( Prev->regis.aep );
	  New->regis.rtmpreq = htonl( Prev->regis.rtmpreq );
	  New->regis.zip = htonl( Prev->regis.zip );
	  New->regis.adsp = htonl( Prev->regis.adsp );
	  New->regis.new_ethernet_count = htonl( Prev->regis.new_ethernet_count );
	  New->regis.unknown_type = htonl( Prev->regis.unknown_type );
	  break;
      }  /* case 3 */
  }  /* switch based on needed conversion */

  if (options.ip_option)
  {
	New->ip_types.count = New->ip_protocol_count;
	tally_ntoh( byteorder, New, Prev, &New->ip_types, &Prev->ip_types );
  }

  tally_ntoh( byteorder, New, Prev, &New->prot, &Prev->prot );

  if (options.tcp_option)
  {
	New->tcp_port.count = New->tcp_port_ctr;
	tally_ntoh( byteorder, New, Prev, &New->tcp_port, &Prev->tcp_port );
  }

  if (options.udp_option)
  {
	New->udp_port.count = New->udp_port_ctr;
	tally_ntoh( byteorder, New, Prev, &New->udp_port, &Prev->udp_port );
  }

  if (options.sap_option)
  {
	New->sap_types.count = New->sap_count ;
	tally_ntoh( byteorder, New, Prev, &New->sap_types, &Prev->sap_types );
  }

}
