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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // in_chk.h - IPv6/IPv4 checksum module
15 // Raw Internet Checksum computation from RMBufChain.
33 /** Checksum calculation.
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);
45 inline TUint32 Sum32();
47 inline void Reverse();
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);
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);
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);
68 TUint32 iSum; // 32-bit sum in network byte order
73 // TInet6Checksum Template.
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
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
90 class TInet6Checksum : public TInet6Packet<T>
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();
103 // Inline methods for TChecksum
106 inline void TChecksum::Init(TUint16 aSum)
108 iSum = ~aSum & 0xffff;
111 inline void TChecksum::Add(const TUint16 *aPtr, TInt aLength)
113 iSum += Calculate(aPtr, aLength);
116 inline void TChecksum::AddHi(TUint8 aByte)
118 iSum += (aByte << 8);
121 inline void TChecksum::AddLo(TUint8 aByte)
126 // Add halfword in network byte order
127 inline void TChecksum::Add(TUint16 aHalfWord)
132 // Add word in network byte order
133 inline void TChecksum::Add(TUint32 aWord)
136 iSum += aWord & 0xffff;
139 // Add halfword in host byte order
140 inline void TChecksum::AddH(TUint16 aHalfWord)
142 __DEBUG_ONLY (const TInt one = 1;)
143 ASSERT(*(TUint8*)&one); //check that we are little-endian
145 iSum += ((aHalfWord << 8) | (aHalfWord >> 8)) & 0xffff;
148 // Add word in host byte order
149 inline void TChecksum::AddH(TUint32 aWord)
151 __DEBUG_ONLY (const TInt one = 1;)
152 ASSERT(*(TUint8*)&one); //check that we are little-endian
154 iSum += (aWord >> 24); // add octet 3
155 iSum += (aWord >> 8) & 0xffff, // add octets 2-1
156 iSum += (aWord << 8) & 0xff00; // add octet 0
159 // Fold 32-bit sum into 16 bits
160 inline void TChecksum::Fold()
165 // Return 16-bit inverted checksum
166 inline TUint32 TChecksum::Sum()
168 return Fold(iSum) ^ 0xffff;
171 // Return 32-bit intermediate sum
172 inline TUint32 TChecksum::Sum32()
177 // Reverse checksum direction. Can be used to back out partial sums.
178 inline void TChecksum::Reverse()
183 inline TUint32 TChecksum::Fold(TUint32 aSum)
185 aSum = (aSum >> 16) + (aSum & 0xffff); // Max: 0x0001fffe
186 aSum += (aSum >> 16); // Max: 0x0001ffff
187 return aSum & 0xffff; // Truncate to 16 bits
190 inline TUint16 TChecksum::ComplementedFold(TUint32 aSum)
192 return (TUint16)~Fold(aSum);
196 void TInet6Checksum<T>::ComputeChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
199 this->iHdr->SetChecksum(0);
200 sum.Add(aPacket, aInfo, aOffset);
201 this->iHdr->SetChecksum(sum.Sum());
205 TBool TInet6Checksum<T>::VerifyChecksum(RMBufChain &aPacket, const RMBufPktInfo *aInfo, TInt aOffset)
208 sum.Add(aPacket, aInfo, aOffset);
212 // The following are mainly for the IPv4 Header checksum
215 void TInet6Checksum<T>::ComputeChecksum()
218 this->iHdr->SetChecksum(0);
219 sum.Add((TUint16 *)(this->iHdr), this->iHdr->HeaderLength());
220 this->iHdr->SetChecksum(sum.Sum());
224 TBool TInet6Checksum<T>::VerifyChecksum()
227 sum.Add((TUint16*)(this->iHdr), this->iHdr->HeaderLength());