/******************************************************************************
*                                                                             *
*   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 *
*                                                                             *
******************************************************************************/



/*
 * Accumulate cksm as body parts seen 
 */

/* TODO - this is actually useless at present - alignment differences will produce different answers for smae object !!!!! */

void
body_in_cksm(prec_t *pp, tcp_conn_t *tconnp)
{
  int nleft = pp->len;
  unsigned short *w;
  unsigned int sum = HTTP_REP_CKSM_ACCUM;
  
  /*
   *  Our algorithm is simple, using a 32 bit accumulator (sum),
   *  we add sequential 16 bit words to it, and at the end, fold
   *  back all the carry bits from the top 16 bits into the lower
   *  16 bits.
   */

  /* get alignment right */
  if ((long)pp->buf & 0x1)
    {
      sum += *pp->buf;
      nleft--;
      w = (unsigned short *)(pp->buf + 1);
    }
  else
    {
      w = (unsigned short *)pp->buf;
    }
      
  while (nleft > 1)  
    {
      sum += *w++;
      nleft -= 2;
    }
  
  /* mop up an odd byte, if necessary */
  if (nleft == 1)
    sum += *(u_char *)w;

  HTTP_REP_CKSM_ACCUM = sum;

  return;
}

/* 
 * Tidy up cksum at body end 
 */

unsigned short 
fold_body_cksm(tcp_conn_t *tconnp)
{

#ifdef __alpha__
  unsigned int sum = HTTP_REP_CKSM_ACCUM;
  
  /*
   * add back carry outs from top 16 bits to low 16 bits
   */
  sum = (sum >> 16) + (sum & 0xffff);   /* add hi 16 to low 16 */
  sum += (sum >> 16);                   /* add carry */
  return ~sum;                                /* truncate to 16 bits */
#else

return HTTP_REP_CKSM_ACCUM;

#endif
}
