1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/in_chk.h Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,230 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// 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
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// in_chk.h - IPv6/IPv4 checksum module
1.18 +// Raw Internet Checksum computation from RMBufChain.
1.19 +//
1.20 +
1.21 +
1.22 +
1.23 +/**
1.24 + @file in_chk.h
1.25 + @publishedAll
1.26 + @released
1.27 +*/
1.28 +
1.29 +#ifndef __IN_CHK_H__
1.30 +#define __IN_CHK_H__
1.31 +
1.32 +#include <nifmbuf.h>
1.33 +#include "in_pkt.h"
1.34 +
1.35 +/** Checksum calculation.
1.36 +
1.37 +@publishedAll
1.38 +@released
1.39 +*/
1.40 +class TChecksum {
1.41 +public:
1.42 + // TChecksum can be initialized with an old inverted checksum
1.43 + TChecksum::TChecksum(TUint16 aSum = ~0) : iSum((TUint16)~aSum) {}
1.44 + inline void Init(TUint16 aSum = ~0);
1.45 +
1.46 + inline TUint32 Sum();
1.47 + inline TUint32 Sum32();
1.48 + inline void Fold();
1.49 + inline void Reverse();
1.50 +
1.51 + // Complex Add methods
1.52 + IMPORT_C void Add(RMBufChain &aPacket, TInt aOffset);
1.53 + IMPORT_C void Add(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset);
1.54 +
1.55 + // Inline Add methods
1.56 + inline void Add(const TUint16 *aPtr, TInt aLength);
1.57 + inline void AddHi(TUint8 aByte);
1.58 + inline void AddLo(TUint8 aByte);
1.59 + inline void Add(TUint16 aHalfWord);
1.60 + inline void Add(TUint32 aWord);
1.61 + inline void AddH(TUint16 aHalfWord);
1.62 + inline void AddH(TUint32 aWord);
1.63 +
1.64 + // Static methods
1.65 + static inline TUint32 Fold(TUint32 aSum);
1.66 + static inline TUint16 ComplementedFold(TUint32 aSum);
1.67 + IMPORT_C static TUint32 Calculate(const TUint16 *aPtr, TInt aLength);
1.68 +
1.69 +private:
1.70 + TUint32 iSum; // 32-bit sum in network byte order
1.71 +};
1.72 +
1.73 +
1.74 +/**
1.75 +// TInet6Checksum Template.
1.76 +//
1.77 +// This template class provides utilitlies to compute and check
1.78 +// IPv6 Upper Layer Checksums
1.79 +// These are not merged with the TInet6Packet class, because that
1.80 +// class is intended (and is used) for all headers, not just upper
1.81 +// layers.
1.82 +//
1.83 +// The template parameter (Header class) must
1.84 +// - have Checksum() method
1.85 +// - have SetChecksum() method
1.86 +// - the checkum in header must be aligned to 16 bit word
1.87 +//
1.88 +// @publishedAll
1.89 +// @released
1.90 +*/
1.91 +template <class T>
1.92 +class TInet6Checksum : public TInet6Packet<T>
1.93 + {
1.94 +public:
1.95 + TInet6Checksum() {}
1.96 + TInet6Checksum(RMBufChain &aPacket) : TInet6Packet<T>(aPacket) {}
1.97 + TInet6Checksum(RMBufChain &aPacket, TInt aOffset) : TInet6Packet<T>(aPacket, aOffset) {}
1.98 + void ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0);
1.99 + TBool VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0);
1.100 + void ComputeChecksum();
1.101 + TBool VerifyChecksum();
1.102 + };
1.103 +
1.104 +//
1.105 +// Inline methods for TChecksum
1.106 +//
1.107 +
1.108 +inline void TChecksum::Init(TUint16 aSum)
1.109 +{
1.110 + iSum = ~aSum & 0xffff;
1.111 +}
1.112 +
1.113 +inline void TChecksum::Add(const TUint16 *aPtr, TInt aLength)
1.114 +{
1.115 + iSum += Calculate(aPtr, aLength);
1.116 +}
1.117 +
1.118 +inline void TChecksum::AddHi(TUint8 aByte)
1.119 +{
1.120 + iSum += (aByte << 8);
1.121 +}
1.122 +
1.123 +inline void TChecksum::AddLo(TUint8 aByte)
1.124 +{
1.125 + iSum += aByte;
1.126 +}
1.127 +
1.128 +// Add halfword in network byte order
1.129 +inline void TChecksum::Add(TUint16 aHalfWord)
1.130 +{
1.131 + iSum += aHalfWord;
1.132 +}
1.133 +
1.134 +// Add word in network byte order
1.135 +inline void TChecksum::Add(TUint32 aWord)
1.136 +{
1.137 + iSum += aWord >> 16;
1.138 + iSum += aWord & 0xffff;
1.139 +}
1.140 +
1.141 +// Add halfword in host byte order
1.142 +inline void TChecksum::AddH(TUint16 aHalfWord)
1.143 +{
1.144 + __DEBUG_ONLY (const TInt one = 1;)
1.145 + ASSERT(*(TUint8*)&one); //check that we are little-endian
1.146 +
1.147 + iSum += ((aHalfWord << 8) | (aHalfWord >> 8)) & 0xffff;
1.148 +}
1.149 +
1.150 +// Add word in host byte order
1.151 +inline void TChecksum::AddH(TUint32 aWord)
1.152 +{
1.153 + __DEBUG_ONLY (const TInt one = 1;)
1.154 + ASSERT(*(TUint8*)&one); //check that we are little-endian
1.155 +
1.156 + iSum += (aWord >> 24); // add octet 3
1.157 + iSum += (aWord >> 8) & 0xffff, // add octets 2-1
1.158 + iSum += (aWord << 8) & 0xff00; // add octet 0
1.159 +}
1.160 +
1.161 +// Fold 32-bit sum into 16 bits
1.162 +inline void TChecksum::Fold()
1.163 +{
1.164 + iSum = Fold(iSum);
1.165 +}
1.166 +
1.167 +// Return 16-bit inverted checksum
1.168 +inline TUint32 TChecksum::Sum()
1.169 +{
1.170 + return Fold(iSum) ^ 0xffff;
1.171 +}
1.172 +
1.173 +// Return 32-bit intermediate sum
1.174 +inline TUint32 TChecksum::Sum32()
1.175 +{
1.176 + return iSum;
1.177 +}
1.178 +
1.179 +// Reverse checksum direction. Can be used to back out partial sums.
1.180 +inline void TChecksum::Reverse()
1.181 +{
1.182 + iSum = Sum();
1.183 +}
1.184 +
1.185 +inline TUint32 TChecksum::Fold(TUint32 aSum)
1.186 +{
1.187 + aSum = (aSum >> 16) + (aSum & 0xffff); // Max: 0x0001fffe
1.188 + aSum += (aSum >> 16); // Max: 0x0001ffff
1.189 + return aSum & 0xffff; // Truncate to 16 bits
1.190 +}
1.191 +
1.192 +inline TUint16 TChecksum::ComplementedFold(TUint32 aSum)
1.193 +{
1.194 + return (TUint16)~Fold(aSum);
1.195 +}
1.196 +
1.197 +template <class T>
1.198 +void TInet6Checksum<T>::ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
1.199 + {
1.200 + TChecksum sum;
1.201 + this->iHdr->SetChecksum(0);
1.202 + sum.Add(aPacket, aInfo, aOffset);
1.203 + this->iHdr->SetChecksum(sum.Sum());
1.204 + }
1.205 +
1.206 +template <class T>
1.207 +TBool TInet6Checksum<T>::VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
1.208 + {
1.209 + TChecksum sum;
1.210 + sum.Add(aPacket, aInfo, aOffset);
1.211 + return !sum.Sum();
1.212 + }
1.213 +//
1.214 +// The following are mainly for the IPv4 Header checksum
1.215 +//
1.216 +template <class T>
1.217 +void TInet6Checksum<T>::ComputeChecksum()
1.218 + {
1.219 + TChecksum sum;
1.220 + this->iHdr->SetChecksum(0);
1.221 + sum.Add((TUint16 *)(this->iHdr), this->iHdr->HeaderLength());
1.222 + this->iHdr->SetChecksum(sum.Sum());
1.223 + }
1.224 +
1.225 +template <class T>
1.226 +TBool TInet6Checksum<T>::VerifyChecksum()
1.227 + {
1.228 + TChecksum sum;
1.229 + sum.Add((TUint16*)(this->iHdr), this->iHdr->HeaderLength());
1.230 + return !sum.Sum();
1.231 + }
1.232 +
1.233 +#endif