/*
    NetUDPChecksum.h, Copyright  (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/UDP/NetUDPChecksum.c,v $
    Author(s):
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Creation Date:
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/
#include "NetUDPChecksum.h"
#include "NetBuf.h"
#include "NetAttr.h"
#include "NetIPModule.h"
#include "NetIPChecksum.h"
#include "NetByteorder.h"


int netudpChecksum(NetBuf buf, NetAttrs attrs, int len)
{
  netudp_pseudo_header	phdr;
  unsigned short			tmp;

  // Construct the Pseudo-header by adding a false-NetBuf
  phdr.netbuf.start= NETBUF_HEADERSIZE;
  phdr.netbuf.end  = sizeof(netudp_pseudo_header);
  phdr.netbuf.next = buf;

  // source address
  if(!netattrGet(attrs, NETATTR_IP_LOCAL_0, &tmp))
    return -1;
  phdr.saddr0 = tmp;
  if(!netattrGet(attrs, NETATTR_IP_LOCAL_1, &tmp))
    return -1;
  phdr.saddr1 = tmp;
  if(!netattrGet(attrs, NETATTR_IP_LOCAL_2, &tmp))
    return -1;
  phdr.saddr2 = tmp;
  if(!netattrGet(attrs, NETATTR_IP_LOCAL_3, &tmp))
    return -1;
  phdr.saddr3 = tmp;

  // dest address
  if(!netattrGet(attrs, NETATTR_IP_REMOTE_0, &tmp))
    return -1;
  phdr.daddr0 = tmp;
  if(!netattrGet(attrs, NETATTR_IP_REMOTE_1, &tmp))
    return -1;
  phdr.daddr1 = tmp;
  if(!netattrGet(attrs, NETATTR_IP_REMOTE_2, &tmp))
    return -1;
  phdr.daddr2 = tmp;
  if(!netattrGet(attrs, NETATTR_IP_REMOTE_3, &tmp))
    return -1;
  phdr.daddr3 = tmp;

  phdr.zero = 0;
  phdr.protocol = NETIP_PROTOCOL_UDP;
  phdr.len = htons(len);

  // calculate checksum
  return netipChecksum(&phdr.netbuf,len+sizeof(netudp_pseudo_header));
}
