www.pudn.com > ids_snort.zip > checksum.c
/* $Id: checksum.c,v 1.2 2001/01/02 08:06:00 roesch Exp $ */ /* ** Copyright (C) 1998,1999,2000,2001 Martin Roesch** ** This program 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. ** ** This program 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 this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "checksum.h" /* * Function: checksum(u_int16_t *, u_int32_t, u_int16_t *, u_int32_t) * * Purpose: Huh huh, math.... * * Arguments: b1 => pointer to data set one * len1 => length of data set one * b2 => pointer to data set two * len2 => length of data set two * * Returns: csum => the calculated checksum for the given data */ u_int16_t checksum(u_int16_t *b1, u_int32_t len1, u_int16_t *b2, u_int32_t len2) { u_int32_t sum = 0; if(b1 != (u_int16_t *)NULL) { while(len1 > 1) { sum += *((u_int16_t *)b1 ++); if(sum & 0x80000000) { sum = (sum & 0xffff) + (sum >> 16); } len1 -= 2; } /* we'll have problems if b2 exists and len1 is odd */ if(len1) { sum += (u_int16_t) * (u_int8_t*) b1; } } if(b2 != (u_int16_t*)NULL) { while(len2 > 1) { sum += *((u_int16_t*)b2 ++); if(sum & 0x80000000) { sum = (sum & 0xffff) + (sum >> 16); } len2 -= 2; } if(len2) { sum += (u_int16_t) * (u_int8_t*) b2; } } while(sum >> 16) sum = (sum & 0xffff) + (sum >> 16); return ~sum; }