/*
    Copyright 2000 (c) by Boris Lutz,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Net/Modules/ICMP/NetICMPModuleDown.c,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/


#include "NetModulesNew.h"
#include "NetAttr.h"
#include "LWThreads.h"
#include "NetBitFields.h"
#include "NetByteorder.h"
#include "NetDebug.h"
#include "NetIPModule.h"
#include "NetIPChecksum.h"
#include "NetICMPModule.h"


void netICMPModuleDownInit (NetModule this)
{
  // XXX what should I do?
  return;
}


int netICMPModuleDownConfig (NetModule this, Message *msg)
{
  /* XXX protocol modules normaly shouldn't need to be configured */
  return 0;
}


void netICMPModuleDownMain (LWPool lw, ThreadArg arg)
{
  NetModule		modDesc = (NetModule) arg;
  NetICMPHdr		*hdr;
  NetBuf			data;
  NetAttrs		meta;
  unsigned short	val;


  while (1)
  {
    netmodRecv (lw, &data, &meta);
    PACKSTART(modDesc);
    if (netbufAddHeadSpace(&data, sizeof(NetICMPHdr)) != 1)
    {
      PACKERROR(modDesc);
      netmodRIP (lw, data, meta,
                 "netICMP: Failed to allocate header!\n");
      continue;
    }
    hdr = (NetICMPHdr*) NETBUF_DATA(data);

    /* Get TYPE */
    if (netattrGet (meta, NETATTR_ICMP_TYPE, &val) )
    {
      hdr->type = val;
    }
    else
    {
      netdbgDisplay(NETDEBUG_ICMP, "netip: Failed to get attribute (TYPE)! Setting to default!\n");
      hdr->type = NETICMP_DEFAULT_TYPE;
    }

    /* Get CODE */
    if (netattrGet(meta, NETATTR_ICMP_CODE, &val) )
    {
      hdr->code = val;
    }
    else
    {
      netdbgDisplay(NETDEBUG_ICMP, "netip: Failed to get attribute (CODE)! Setting to default!\n");
      hdr->code = NETICMP_DEFAULT_CODE;
    }

    /* Set Checksum */
    if (! netattrGet(meta, NETATTR_ICMP_CHECKSUM, &val))
    {
      hdr->checksum = 0;
      hdr->checksum = htons( (u16)netipChecksum(data, netbufLen(data)) );
    }
    else
    {
      hdr->checksum = htons( val );
    }

    /* Finished: send the packet */
    PACKDONE(modDesc);
    netmodSend (lw, CHAINNEXT(modDesc), data, meta);
  }
}
