diff -r 666f914201fb -r 2fe1408b6811 epoc32/include/in_chk.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/epoc32/include/in_chk.h Tue Mar 16 16:12:26 2010 +0000 @@ -0,0 +1,230 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members +// which accompanies this distribution, and is available +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// in_chk.h - IPv6/IPv4 checksum module +// Raw Internet Checksum computation from RMBufChain. +// + + + +/** + @file in_chk.h + @publishedAll + @released +*/ + +#ifndef __IN_CHK_H__ +#define __IN_CHK_H__ + +#include +#include "in_pkt.h" + +/** Checksum calculation. + +@publishedAll +@released +*/ +class TChecksum { +public: + // TChecksum can be initialized with an old inverted checksum + TChecksum::TChecksum(TUint16 aSum = ~0) : iSum((TUint16)~aSum) {} + inline void Init(TUint16 aSum = ~0); + + inline TUint32 Sum(); + inline TUint32 Sum32(); + inline void Fold(); + inline void Reverse(); + + // Complex Add methods + IMPORT_C void Add(RMBufChain &aPacket, TInt aOffset); + IMPORT_C void Add(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset); + + // Inline Add methods + inline void Add(const TUint16 *aPtr, TInt aLength); + inline void AddHi(TUint8 aByte); + inline void AddLo(TUint8 aByte); + inline void Add(TUint16 aHalfWord); + inline void Add(TUint32 aWord); + inline void AddH(TUint16 aHalfWord); + inline void AddH(TUint32 aWord); + + // Static methods + static inline TUint32 Fold(TUint32 aSum); + static inline TUint16 ComplementedFold(TUint32 aSum); + IMPORT_C static TUint32 Calculate(const TUint16 *aPtr, TInt aLength); + +private: + TUint32 iSum; // 32-bit sum in network byte order +}; + + +/** +// TInet6Checksum Template. +// +// This template class provides utilitlies to compute and check +// IPv6 Upper Layer Checksums +// These are not merged with the TInet6Packet class, because that +// class is intended (and is used) for all headers, not just upper +// layers. +// +// The template parameter (Header class) must +// - have Checksum() method +// - have SetChecksum() method +// - the checkum in header must be aligned to 16 bit word +// +// @publishedAll +// @released +*/ +template +class TInet6Checksum : public TInet6Packet + { +public: + TInet6Checksum() {} + TInet6Checksum(RMBufChain &aPacket) : TInet6Packet(aPacket) {} + TInet6Checksum(RMBufChain &aPacket, TInt aOffset) : TInet6Packet(aPacket, aOffset) {} + void ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0); + TBool VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0); + void ComputeChecksum(); + TBool VerifyChecksum(); + }; + +// +// Inline methods for TChecksum +// + +inline void TChecksum::Init(TUint16 aSum) +{ + iSum = ~aSum & 0xffff; +} + +inline void TChecksum::Add(const TUint16 *aPtr, TInt aLength) +{ + iSum += Calculate(aPtr, aLength); +} + +inline void TChecksum::AddHi(TUint8 aByte) +{ + iSum += (aByte << 8); +} + +inline void TChecksum::AddLo(TUint8 aByte) +{ + iSum += aByte; +} + +// Add halfword in network byte order +inline void TChecksum::Add(TUint16 aHalfWord) +{ + iSum += aHalfWord; +} + +// Add word in network byte order +inline void TChecksum::Add(TUint32 aWord) +{ + iSum += aWord >> 16; + iSum += aWord & 0xffff; +} + +// Add halfword in host byte order +inline void TChecksum::AddH(TUint16 aHalfWord) +{ + __DEBUG_ONLY (const TInt one = 1;) + ASSERT(*(TUint8*)&one); //check that we are little-endian + + iSum += ((aHalfWord << 8) | (aHalfWord >> 8)) & 0xffff; +} + +// Add word in host byte order +inline void TChecksum::AddH(TUint32 aWord) +{ + __DEBUG_ONLY (const TInt one = 1;) + ASSERT(*(TUint8*)&one); //check that we are little-endian + + iSum += (aWord >> 24); // add octet 3 + iSum += (aWord >> 8) & 0xffff, // add octets 2-1 + iSum += (aWord << 8) & 0xff00; // add octet 0 +} + +// Fold 32-bit sum into 16 bits +inline void TChecksum::Fold() +{ + iSum = Fold(iSum); +} + +// Return 16-bit inverted checksum +inline TUint32 TChecksum::Sum() +{ + return Fold(iSum) ^ 0xffff; +} + +// Return 32-bit intermediate sum +inline TUint32 TChecksum::Sum32() +{ + return iSum; +} + +// Reverse checksum direction. Can be used to back out partial sums. +inline void TChecksum::Reverse() +{ + iSum = Sum(); +} + +inline TUint32 TChecksum::Fold(TUint32 aSum) +{ + aSum = (aSum >> 16) + (aSum & 0xffff); // Max: 0x0001fffe + aSum += (aSum >> 16); // Max: 0x0001ffff + return aSum & 0xffff; // Truncate to 16 bits +} + +inline TUint16 TChecksum::ComplementedFold(TUint32 aSum) +{ + return (TUint16)~Fold(aSum); +} + +template +void TInet6Checksum::ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset) + { + TChecksum sum; + this->iHdr->SetChecksum(0); + sum.Add(aPacket, aInfo, aOffset); + this->iHdr->SetChecksum(sum.Sum()); + } + +template +TBool TInet6Checksum::VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset) + { + TChecksum sum; + sum.Add(aPacket, aInfo, aOffset); + return !sum.Sum(); + } +// +// The following are mainly for the IPv4 Header checksum +// +template +void TInet6Checksum::ComputeChecksum() + { + TChecksum sum; + this->iHdr->SetChecksum(0); + sum.Add((TUint16 *)(this->iHdr), this->iHdr->HeaderLength()); + this->iHdr->SetChecksum(sum.Sum()); + } + +template +TBool TInet6Checksum::VerifyChecksum() + { + TChecksum sum; + sum.Add((TUint16*)(this->iHdr), this->iHdr->HeaderLength()); + return !sum.Sum(); + } + +#endif