epoc32/include/in_chk.h
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
parent 2 2fe1408b6811
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // in_chk.h - IPv6/IPv4 checksum module
    15 // Raw Internet Checksum computation from RMBufChain.
    16 //
    17 
    18 
    19 
    20 /**
    21  @file in_chk.h
    22  @publishedAll
    23  @released
    24 */
    25 
    26 #ifndef __IN_CHK_H__
    27 #define __IN_CHK_H__
    28 
    29 #include "in_pkt.h"
    30 class RMBufChain;
    31 class RMBufPktInfo;
    32 
    33 /** Checksum calculation.
    34 
    35 @publishedAll
    36 @released
    37 */
    38 class TChecksum {
    39 public:
    40         // TChecksum can be initialized with an old inverted checksum
    41         TChecksum(TUint16 aSum = ~0) : iSum((TUint16)~aSum) {}
    42 	inline void Init(TUint16 aSum = ~0);
    43 
    44 	inline TUint32 Sum();
    45         inline TUint32 Sum32();
    46         inline void Fold();
    47         inline void Reverse();
    48 
    49         // Complex Add methods
    50         IMPORT_C void Add(RMBufChain &aPacket, TInt aOffset);
    51         IMPORT_C void Add(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset);
    52 
    53         // Inline Add methods
    54         inline void Add(const TUint16 *aPtr, TInt aLength);
    55         inline void AddHi(TUint8 aByte);
    56         inline void AddLo(TUint8 aByte);
    57         inline void Add(TUint16 aHalfWord);
    58         inline void Add(TUint32 aWord);
    59         inline void AddH(TUint16 aHalfWord);
    60         inline void AddH(TUint32 aWord);
    61 
    62         // Static methods
    63         static inline TUint32 Fold(TUint32 aSum);
    64         static inline TUint16 ComplementedFold(TUint32 aSum);
    65         IMPORT_C static TUint32 Calculate(const TUint16 *aPtr, TInt aLength);
    66 
    67 private:
    68 	TUint32	iSum;   // 32-bit sum in network byte order
    69 };
    70 
    71 
    72 /**
    73 // TInet6Checksum Template.
    74 //
    75 //		This template class provides utilitlies to compute and check
    76 //		IPv6 Upper Layer Checksums
    77 //		These are not merged with the TInet6Packet class, because that
    78 //		class is intended (and is used) for all headers, not just upper
    79 //		layers.
    80 //
    81 //	The template parameter (Header class) must
    82 //		- have Checksum() method
    83 //		- have SetChecksum() method
    84 //		- the checkum in header must be aligned to 16 bit word
    85 //
    86 // @publishedAll
    87 // @released
    88 */
    89 template <class T>
    90 class TInet6Checksum : public TInet6Packet<T>
    91 	{
    92 public:
    93 	TInet6Checksum() {}
    94 	TInet6Checksum(RMBufChain &aPacket) : TInet6Packet<T>(aPacket) {}
    95 	TInet6Checksum(RMBufChain &aPacket, TInt aOffset) : TInet6Packet<T>(aPacket, aOffset) {}
    96 	void ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0);
    97 	TBool VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0);
    98 	void ComputeChecksum();
    99 	TBool VerifyChecksum();
   100 	};
   101 
   102 //
   103 // Inline methods for TChecksum
   104 //
   105 
   106 inline void TChecksum::Init(TUint16 aSum)
   107 {
   108         iSum = ~aSum & 0xffff;
   109 }
   110 
   111 inline void TChecksum::Add(const TUint16 *aPtr, TInt aLength)
   112 {
   113 	iSum += Calculate(aPtr, aLength);
   114 }
   115 
   116 inline void TChecksum::AddHi(TUint8 aByte)
   117 {
   118         iSum += (aByte << 8);
   119 }
   120 
   121 inline void TChecksum::AddLo(TUint8 aByte)
   122 {
   123         iSum += aByte;
   124 }
   125 
   126 // Add halfword in network byte order
   127 inline void TChecksum::Add(TUint16 aHalfWord)
   128 {
   129         iSum += aHalfWord;
   130 }
   131 
   132 // Add word in network byte order
   133 inline void TChecksum::Add(TUint32 aWord)
   134 {
   135 	iSum += aWord >> 16;
   136         iSum += aWord & 0xffff;
   137 }
   138 
   139 // Add halfword in host byte order
   140 inline void TChecksum::AddH(TUint16 aHalfWord)
   141 {
   142 		__DEBUG_ONLY (const TInt one = 1;)
   143 		ASSERT(*(TUint8*)&one); //check that we are little-endian
   144 
   145 		iSum += ((aHalfWord << 8) | (aHalfWord >> 8)) & 0xffff;
   146 }
   147 
   148 // Add word in host byte order
   149 inline void TChecksum::AddH(TUint32 aWord)
   150 {
   151 		__DEBUG_ONLY (const TInt one = 1;)
   152 		ASSERT(*(TUint8*)&one); //check that we are little-endian
   153 
   154         iSum += (aWord >> 24);          // add octet  3
   155         iSum += (aWord >> 8) & 0xffff,  // add octets 2-1
   156         iSum += (aWord << 8) & 0xff00;  // add octet  0
   157 }
   158 
   159 // Fold 32-bit sum into 16 bits
   160 inline void TChecksum::Fold()
   161 {
   162         iSum = Fold(iSum);
   163 }
   164 
   165 // Return 16-bit inverted checksum
   166 inline TUint32 TChecksum::Sum()
   167 {
   168         return Fold(iSum) ^ 0xffff;
   169 }
   170 
   171 // Return 32-bit intermediate sum
   172 inline TUint32 TChecksum::Sum32()
   173 {
   174         return iSum;
   175 }
   176 
   177 // Reverse checksum direction. Can be used to back out partial sums.
   178 inline void TChecksum::Reverse()
   179 {
   180         iSum = Sum();
   181 }
   182 
   183 inline TUint32 TChecksum::Fold(TUint32 aSum)
   184 {
   185 	aSum = (aSum >> 16) + (aSum & 0xffff);  // Max: 0x0001fffe
   186 	aSum += (aSum >> 16);                   // Max: 0x0001ffff
   187         return aSum & 0xffff;                   // Truncate to 16 bits
   188 }
   189 
   190 inline TUint16 TChecksum::ComplementedFold(TUint32 aSum)
   191 {
   192         return (TUint16)~Fold(aSum);
   193 }
   194 
   195 template <class T>
   196 void TInet6Checksum<T>::ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
   197 	{
   198         TChecksum sum;
   199 	this->iHdr->SetChecksum(0);
   200         sum.Add(aPacket, aInfo, aOffset);
   201 	this->iHdr->SetChecksum(sum.Sum());
   202 	}
   203 
   204 template <class T>
   205 TBool TInet6Checksum<T>::VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
   206 	{
   207         TChecksum sum;
   208         sum.Add(aPacket, aInfo, aOffset);
   209         return !sum.Sum();
   210 	}
   211 //
   212 // The following are mainly for the IPv4 Header checksum
   213 //
   214 template <class T>
   215 void TInet6Checksum<T>::ComputeChecksum()
   216 	{
   217         TChecksum sum;
   218 	this->iHdr->SetChecksum(0);
   219         sum.Add((TUint16 *)(this->iHdr), this->iHdr->HeaderLength());
   220 	this->iHdr->SetChecksum(sum.Sum());
   221 	}
   222 
   223 template <class T>
   224 TBool TInet6Checksum<T>::VerifyChecksum()
   225 	{
   226         TChecksum sum;
   227         sum.Add((TUint16*)(this->iHdr), this->iHdr->HeaderLength());
   228         return !sum.Sum();
   229 	}
   230 
   231 #endif