|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "ikev2trafficselector.h" |
|
19 #include "ikev2const.h" |
|
20 #include "ikev2payloads.h" |
|
21 |
|
22 TIkeV2TrafficSelector* TIkeV2TrafficSelector::NewL(const TDesC8& aIkeV2TrafficSector) |
|
23 { |
|
24 static const TUint16 KIpv4SelectorLength = 16; |
|
25 static const TUint16 KIpv6SelectorLength = 48; |
|
26 |
|
27 if (aIkeV2TrafficSector.Length() != KIpv4SelectorLength && |
|
28 aIkeV2TrafficSector.Length() != KIpv6SelectorLength) |
|
29 { |
|
30 User::Leave(KErrArgument); |
|
31 } |
|
32 |
|
33 |
|
34 const TTrafficSelector* selector = |
|
35 reinterpret_cast<const TTrafficSelector*>(aIkeV2TrafficSector.Ptr()); |
|
36 |
|
37 |
|
38 TInetAddr startAddr; |
|
39 TInetAddr endAddr; |
|
40 |
|
41 const TUint8* addresses = selector->Addresses(); |
|
42 if ( selector->Type() == TS_IPV4_ADDR_RANGE ) |
|
43 { |
|
44 if (aIkeV2TrafficSector.Length() != KIpv4SelectorLength) |
|
45 { |
|
46 User::Leave(KErrArgument); |
|
47 } |
|
48 TUint32 startA = *(reinterpret_cast<const TUint32*>(addresses)); |
|
49 TUint32 endA = *(reinterpret_cast<const TUint32*>(addresses + 4)); |
|
50 |
|
51 BigEndian::Put32(reinterpret_cast<TUint8*>(&startA), startA); |
|
52 BigEndian::Put32(reinterpret_cast<TUint8*>(&endA), endA); |
|
53 |
|
54 startAddr.SetAddress(startA); |
|
55 endAddr.SetAddress(endA); |
|
56 |
|
57 } |
|
58 else |
|
59 { |
|
60 if (aIkeV2TrafficSector.Length() != KIpv6SelectorLength || |
|
61 selector->Type() != TS_IPV6_ADDR_RANGE) |
|
62 { |
|
63 User::Leave(KErrArgument); |
|
64 } |
|
65 TIp6Addr startA; |
|
66 TIp6Addr endA; |
|
67 |
|
68 Mem::Copy(startA.u.iAddr8, addresses, 16); |
|
69 Mem::Copy(endA.u.iAddr8, addresses+16, 16); |
|
70 |
|
71 startAddr.SetAddress(startA); |
|
72 endAddr.SetAddress(endA); |
|
73 } |
|
74 |
|
75 TUint16 startPort = selector->StartPort(); |
|
76 BigEndian::Put16(reinterpret_cast<TUint8*>(&startPort), startPort); |
|
77 startAddr.SetPort(startPort); |
|
78 |
|
79 TUint16 endPort = selector->EndPort(); |
|
80 BigEndian::Put16(reinterpret_cast<TUint8*>(&endPort), endPort); |
|
81 endAddr.SetPort(endPort); |
|
82 |
|
83 return new (ELeave) TIkeV2TrafficSelector(startAddr, endAddr, selector->Protocol()); |
|
84 } |
|
85 |
|
86 |
|
87 TIkeV2TrafficSelector::TIkeV2TrafficSelector(TInetAddr aStartingAddress, TInetAddr aEndingAddress, TUint8 aProtocolId) |
|
88 :iStartingAddress(aStartingAddress), iEndingAddress(aEndingAddress), iProtocolId(aProtocolId) |
|
89 { |
|
90 __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() && |
|
91 iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() && |
|
92 iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant()); |
|
93 |
|
94 iMask = CalcuateMask(); |
|
95 } |
|
96 |
|
97 |
|
98 TIkeV2TrafficSelector::TIkeV2TrafficSelector(const TIkeV2TrafficSelector& aTrafficSelector) |
|
99 { |
|
100 iStartingAddress = aTrafficSelector.iStartingAddress; |
|
101 iEndingAddress = aTrafficSelector.iEndingAddress; |
|
102 |
|
103 iProtocolId = aTrafficSelector.iProtocolId; |
|
104 |
|
105 __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() && |
|
106 iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() && |
|
107 iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant()); |
|
108 iMask = CalcuateMask(); |
|
109 } |
|
110 |
|
111 |
|
112 TInetAddr TIkeV2TrafficSelector::StartingAddress() const |
|
113 { |
|
114 return iStartingAddress; |
|
115 } |
|
116 |
|
117 |
|
118 TInetAddr TIkeV2TrafficSelector::EndingAddress() const |
|
119 { |
|
120 return iEndingAddress; |
|
121 } |
|
122 |
|
123 TInetAddr TIkeV2TrafficSelector::Mask() const |
|
124 { |
|
125 return iMask; |
|
126 } |
|
127 |
|
128 TUint8 TIkeV2TrafficSelector::ProtocolId() const |
|
129 { |
|
130 return iProtocolId; |
|
131 } |
|
132 |
|
133 TUint8 TIkeV2TrafficSelector::Type() const |
|
134 { |
|
135 __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() && |
|
136 iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() && |
|
137 iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant()); |
|
138 |
|
139 if (iStartingAddress.Family() == KAfInet || |
|
140 iStartingAddress.IsV4Compat() || |
|
141 iStartingAddress.IsV4Mapped()) |
|
142 { |
|
143 return TS_IPV4_ADDR_RANGE; |
|
144 } |
|
145 else |
|
146 { |
|
147 return TS_IPV6_ADDR_RANGE; |
|
148 } |
|
149 } |
|
150 |
|
151 |
|
152 HBufC8* TIkeV2TrafficSelector::IdFromTsL() const |
|
153 { |
|
154 TInetAddr idAddr = iStartingAddress; |
|
155 idAddr.SetPort(0); |
|
156 TInt prefix = 0; |
|
157 if (Type() == TS_IPV4_ADDR_RANGE) |
|
158 { |
|
159 TUint32 startIp = iStartingAddress.Address(); |
|
160 TUint32 endIp = iEndingAddress.Address(); |
|
161 TUint32 mask = ~(endIp ^ startIp); |
|
162 TUint32 m = 1; |
|
163 while ( prefix < 32 ) |
|
164 { |
|
165 if ( mask & ( m << prefix) ) |
|
166 break; |
|
167 prefix ++; |
|
168 } |
|
169 prefix = 32 - prefix; |
|
170 idAddr = TInetAddr(startIp); |
|
171 } |
|
172 else |
|
173 { |
|
174 prefix = 128; // NOT IMPLEMENTED YET |
|
175 } |
|
176 |
|
177 HBufC* idString = HBufC::NewLC(512); |
|
178 TPtr idStringPtr = idString->Des(); |
|
179 idAddr.Output(idStringPtr); |
|
180 idStringPtr.AppendFormat(_L("/%d"), prefix); |
|
181 |
|
182 HBufC8* idString8 = HBufC8::NewL(idString->Length()); |
|
183 TPtr8 idString8Ptr = idString8->Des(); |
|
184 idString8Ptr.Copy(*idString); |
|
185 CleanupStack::PopAndDestroy(idString); |
|
186 |
|
187 return idString8; |
|
188 } |
|
189 |
|
190 TInetAddr TIkeV2TrafficSelector::CalcuateMask() const |
|
191 { |
|
192 TInetAddr mask; |
|
193 if ( Type() == TS_IPV4_ADDR_RANGE ) |
|
194 { |
|
195 TUint32 A = iStartingAddress.Address(); |
|
196 TUint32 M = iEndingAddress.Address(); |
|
197 TUint32 X = 0x80000000; |
|
198 TUint32 Y = 0; |
|
199 M = ~(A ^ M); //Gets the bits that are 1 in both addresses |
|
200 for ( TInt i = 0; i < 32; ++i ) |
|
201 { |
|
202 if ( (M & X) == 0 ) |
|
203 { |
|
204 M &= Y; |
|
205 break; |
|
206 } |
|
207 Y |= X; |
|
208 X = (X >> 1); |
|
209 } |
|
210 mask.SetAddress(M); |
|
211 } |
|
212 else |
|
213 { |
|
214 TIp6Addr startAddr = iStartingAddress.Ip6Address(); |
|
215 TIp6Addr endAddr = iEndingAddress.Ip6Address(); |
|
216 TIp6Addr m; |
|
217 Mem::FillZ(m.u.iAddr8, 16); |
|
218 |
|
219 TUint8 c = 0xff; |
|
220 for ( TInt i = 0; i < 16; ++i ) |
|
221 { |
|
222 if ( c == 0xff ) |
|
223 c = (TUint8)(~(startAddr.u.iAddr8[i] ^ endAddr.u.iAddr8[i])); // Convert range to mask |
|
224 if ( (c != 0) && (c != 0xff) ) |
|
225 { |
|
226 TUint8 z = 0x80; |
|
227 TUint8 w = 0; |
|
228 for ( TInt j = 0; j < 8; ++j ) |
|
229 { |
|
230 if ( (c & z) == 0 ) |
|
231 { |
|
232 c &= w; |
|
233 break; |
|
234 } |
|
235 w |= z; |
|
236 z = (TUint8)(z >> 1); |
|
237 } |
|
238 m.u.iAddr8[i] = c; |
|
239 c = 0; |
|
240 } |
|
241 else |
|
242 { |
|
243 m.u.iAddr8[i] = c; |
|
244 } |
|
245 } |
|
246 mask.SetAddress(m); |
|
247 } |
|
248 return mask; |
|
249 } |
|
250 |
|
251 bool TIkeV2TrafficSelector::operator>(const TIkeV2TrafficSelector& aOtherSelector) const |
|
252 { |
|
253 if (Type() != aOtherSelector.Type()) |
|
254 { |
|
255 //types do not match. |
|
256 return false; |
|
257 } |
|
258 |
|
259 if (operator==(aOtherSelector)) |
|
260 { |
|
261 //selectors are equal |
|
262 return false; |
|
263 } |
|
264 |
|
265 return operator>=(aOtherSelector); |
|
266 } |
|
267 |
|
268 |
|
269 bool TIkeV2TrafficSelector::operator<(const TIkeV2TrafficSelector& aOtherSelector) const |
|
270 { |
|
271 if (operator==(aOtherSelector)) |
|
272 { |
|
273 //selectors are equal |
|
274 return false; |
|
275 } |
|
276 |
|
277 //The operator |
|
278 return operator<=(aOtherSelector); |
|
279 } |
|
280 |
|
281 bool TIkeV2TrafficSelector::operator!=(const TIkeV2TrafficSelector& aOtherSelector) const |
|
282 { |
|
283 return !operator==(aOtherSelector); |
|
284 } |
|
285 |
|
286 bool TIkeV2TrafficSelector::operator==(const TIkeV2TrafficSelector& aOtherSelector) const |
|
287 { |
|
288 return (iStartingAddress == aOtherSelector.iStartingAddress && |
|
289 iEndingAddress == aOtherSelector.iEndingAddress); |
|
290 } |
|
291 |
|
292 bool TIkeV2TrafficSelector::operator>=(const TIkeV2TrafficSelector& aOtherSelector) const |
|
293 { |
|
294 if (Type() != aOtherSelector.Type()) |
|
295 { |
|
296 //types do not match. |
|
297 return false; |
|
298 } |
|
299 |
|
300 if (operator==(aOtherSelector)) |
|
301 { |
|
302 //selectors are equal |
|
303 return true; |
|
304 } |
|
305 |
|
306 return !operator<(aOtherSelector); |
|
307 } |
|
308 |
|
309 bool TIkeV2TrafficSelector::operator<=(const TIkeV2TrafficSelector& aOtherSelector) const |
|
310 { |
|
311 if (Type() != aOtherSelector.Type()) |
|
312 { |
|
313 //types do not match. |
|
314 return false; |
|
315 } |
|
316 |
|
317 if (operator==(aOtherSelector)) |
|
318 { |
|
319 //selectors are equal |
|
320 return true; |
|
321 } |
|
322 |
|
323 if (iStartingAddress.Port() < aOtherSelector.iStartingAddress.Port() || |
|
324 iEndingAddress.Port() > aOtherSelector.iEndingAddress.Port()) |
|
325 { |
|
326 //Port range of this is bigger |
|
327 return false; |
|
328 } |
|
329 |
|
330 if (Type() == TS_IPV4_ADDR_RANGE) |
|
331 { |
|
332 if (iStartingAddress.Address() >= aOtherSelector.iStartingAddress.Address() && |
|
333 iEndingAddress.Address() <= aOtherSelector.iEndingAddress.Address()) |
|
334 { |
|
335 return true; |
|
336 } |
|
337 else |
|
338 { |
|
339 return false; |
|
340 } |
|
341 } |
|
342 else |
|
343 { |
|
344 __ASSERT_DEBUG(Type() == TS_IPV6_ADDR_RANGE, User::Invariant()); |
|
345 |
|
346 const TIp6Addr& thisStart = iStartingAddress.Ip6Address(); |
|
347 const TIp6Addr& thisEnd = iEndingAddress.Ip6Address(); |
|
348 |
|
349 const TIp6Addr& otherStart = aOtherSelector.iStartingAddress.Ip6Address(); |
|
350 const TIp6Addr& otherEnd = aOtherSelector.iEndingAddress.Ip6Address(); |
|
351 |
|
352 TInt i; |
|
353 for (i = 0; i < 4; i++) |
|
354 { |
|
355 if (thisStart.u.iAddr32[i] > otherStart.u.iAddr32[i]) |
|
356 { |
|
357 //this start address is bigger |
|
358 break; |
|
359 } |
|
360 else if (thisStart.u.iAddr32[i] < otherStart.u.iAddr32[i]) |
|
361 { |
|
362 //this start address is smaller. |
|
363 return false; |
|
364 } |
|
365 } |
|
366 |
|
367 for (i = 0; i < 4; i++) |
|
368 { |
|
369 if (thisEnd.u.iAddr32[i] < otherEnd.u.iAddr32[i]) |
|
370 { |
|
371 //this end address is smaller |
|
372 break; |
|
373 } |
|
374 else if (thisEnd.u.iAddr32[i] > otherEnd.u.iAddr32[i]) |
|
375 { |
|
376 //this end address is bigger |
|
377 return false; |
|
378 } |
|
379 } |
|
380 return true; |
|
381 } |
|
382 } |
|
383 |
|
384 |