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 the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // in_chk.h - IPv6/IPv4 checksum module
15 // Raw Internet Checksum computation from RMBufChain.
32 /** Checksum calculation.
39 // TChecksum can be initialized with an old inverted checksum
40 TChecksum::TChecksum(TUint16 aSum = ~0) : iSum((TUint16)~aSum) {}
41 inline void Init(TUint16 aSum = ~0);
44 inline TUint32 Sum32();
46 inline void Reverse();
48 // Complex Add methods
49 IMPORT_C void Add(RMBufChain &aPacket, TInt aOffset);
50 IMPORT_C void Add(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset);
53 inline void Add(const TUint16 *aPtr, TInt aLength);
54 inline void AddHi(TUint8 aByte);
55 inline void AddLo(TUint8 aByte);
56 inline void Add(TUint16 aHalfWord);
57 inline void Add(TUint32 aWord);
58 inline void AddH(TUint16 aHalfWord);
59 inline void AddH(TUint32 aWord);
62 static inline TUint32 Fold(TUint32 aSum);
63 static inline TUint16 ComplementedFold(TUint32 aSum);
64 IMPORT_C static TUint32 Calculate(const TUint16 *aPtr, TInt aLength);
67 TUint32 iSum; // 32-bit sum in network byte order
72 // TInet6Checksum Template.
74 // This template class provides utilitlies to compute and check
75 // IPv6 Upper Layer Checksums
76 // These are not merged with the TInet6Packet class, because that
77 // class is intended (and is used) for all headers, not just upper
80 // The template parameter (Header class) must
81 // - have Checksum() method
82 // - have SetChecksum() method
83 // - the checkum in header must be aligned to 16 bit word
89 class TInet6Checksum : public TInet6Packet<T>
93 TInet6Checksum(RMBufChain &aPacket) : TInet6Packet<T>(aPacket) {}
94 TInet6Checksum(RMBufChain &aPacket, TInt aOffset) : TInet6Packet<T>(aPacket, aOffset) {}
95 void ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0);
96 TBool VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset = 0);
97 void ComputeChecksum();
98 TBool VerifyChecksum();
102 // Inline methods for TChecksum
105 inline void TChecksum::Init(TUint16 aSum)
107 iSum = ~aSum & 0xffff;
110 inline void TChecksum::Add(const TUint16 *aPtr, TInt aLength)
112 iSum += Calculate(aPtr, aLength);
115 inline void TChecksum::AddHi(TUint8 aByte)
117 iSum += (aByte << 8);
120 inline void TChecksum::AddLo(TUint8 aByte)
125 // Add halfword in network byte order
126 inline void TChecksum::Add(TUint16 aHalfWord)
131 // Add word in network byte order
132 inline void TChecksum::Add(TUint32 aWord)
135 iSum += aWord & 0xffff;
138 // Add halfword in host byte order
139 inline void TChecksum::AddH(TUint16 aHalfWord)
141 __DEBUG_ONLY (const TInt one = 1;)
142 ASSERT(*(TUint8*)&one); //check that we are little-endian
144 iSum += ((aHalfWord << 8) | (aHalfWord >> 8)) & 0xffff;
147 // Add word in host byte order
148 inline void TChecksum::AddH(TUint32 aWord)
150 __DEBUG_ONLY (const TInt one = 1;)
151 ASSERT(*(TUint8*)&one); //check that we are little-endian
153 iSum += (aWord >> 24); // add octet 3
154 iSum += (aWord >> 8) & 0xffff, // add octets 2-1
155 iSum += (aWord << 8) & 0xff00; // add octet 0
158 // Fold 32-bit sum into 16 bits
159 inline void TChecksum::Fold()
164 // Return 16-bit inverted checksum
165 inline TUint32 TChecksum::Sum()
167 return Fold(iSum) ^ 0xffff;
170 // Return 32-bit intermediate sum
171 inline TUint32 TChecksum::Sum32()
176 // Reverse checksum direction. Can be used to back out partial sums.
177 inline void TChecksum::Reverse()
182 inline TUint32 TChecksum::Fold(TUint32 aSum)
184 aSum = (aSum >> 16) + (aSum & 0xffff); // Max: 0x0001fffe
185 aSum += (aSum >> 16); // Max: 0x0001ffff
186 return aSum & 0xffff; // Truncate to 16 bits
189 inline TUint16 TChecksum::ComplementedFold(TUint32 aSum)
191 return (TUint16)~Fold(aSum);
195 void TInet6Checksum<T>::ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
198 this->iHdr->SetChecksum(0);
199 sum.Add(aPacket, aInfo, aOffset);
200 this->iHdr->SetChecksum(sum.Sum());
204 TBool TInet6Checksum<T>::VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
207 sum.Add(aPacket, aInfo, aOffset);
211 // The following are mainly for the IPv4 Header checksum
214 void TInet6Checksum<T>::ComputeChecksum()
217 this->iHdr->SetChecksum(0);
218 sum.Add((TUint16 *)(this->iHdr), this->iHdr->HeaderLength());
219 this->iHdr->SetChecksum(sum.Sum());
223 TBool TInet6Checksum<T>::VerifyChecksum()
226 sum.Add((TUint16*)(this->iHdr), this->iHdr->HeaderLength());