|
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 // eui_addr.cpp - EUI-xx address structure |
|
15 // |
|
16 |
|
17 #include "eui_addr.h" // This |
|
18 #include <e32std.h> // Mem::*, User::*, TTime |
|
19 #include <e32math.h> // Math::* |
|
20 |
|
21 static void EuiPanic(TEuiPanic aReason); |
|
22 static void EuiPanic(TEuiPanic aReason) |
|
23 { |
|
24 User::Panic(_L("EUI"), aReason); |
|
25 } |
|
26 |
|
27 EXPORT_C TE64Addr::TE64Addr() |
|
28 { |
|
29 SetAddrZero(); |
|
30 } |
|
31 |
|
32 EXPORT_C TE64Addr::TE64Addr(const TE64Addr& aAddr) |
|
33 { |
|
34 SetAddr(aAddr); |
|
35 } |
|
36 |
|
37 EXPORT_C TE64Addr::TE64Addr(const TInt64& aAddr) |
|
38 { |
|
39 SetAddr(aAddr); |
|
40 } |
|
41 |
|
42 EXPORT_C TE64Addr::TE64Addr(const TUint8* aPtr, TUint aLength) |
|
43 { |
|
44 SetAddr(aPtr, aLength); |
|
45 } |
|
46 |
|
47 EXPORT_C void TE64Addr::SetAddr(const TE64Addr& aAddr) |
|
48 { |
|
49 u = aAddr.u; |
|
50 } |
|
51 |
|
52 EXPORT_C void TE64Addr::SetAddr(const TInt64& aAddr) |
|
53 { |
|
54 #ifdef I64HIGH |
|
55 u.iAddr32[0] = I64HIGH(aAddr); |
|
56 u.iAddr32[1] = I64LOW(aAddr); |
|
57 #else |
|
58 u.iAddr32[0] = aAddr.High(); |
|
59 u.iAddr32[1] = aAddr.Low(); |
|
60 #endif |
|
61 } |
|
62 |
|
63 EXPORT_C void TE64Addr::SetAddr(const TUint8* aPtr, TUint aLength) |
|
64 { |
|
65 __ASSERT_DEBUG(aLength <= AddrLen(), EuiPanic(EEuiPanicSourceTooLong)); |
|
66 Mem::Copy(AddrPtr(), aPtr, aLength); |
|
67 } |
|
68 |
|
69 EXPORT_C void TE64Addr::SetGroupBit(TBool aBit) |
|
70 { |
|
71 __ASSERT_DEBUG(aBit == 0 || aBit == 1, EuiPanic(EEuiPanicBitIsNotBit)); |
|
72 |
|
73 // 0 0 0 1 1 2 .. |
|
74 // |0 7 8 5 6 3|.. |
|
75 // +----+----+----+----+----+----+ |
|
76 // |cccc|ccug|cccc|cccc|cccc|cccc|.. |
|
77 // +----+----+----+----+----+----+ |
|
78 |
|
79 if (aBit) |
|
80 { |
|
81 u.iAddr8[0] |= 0x1; |
|
82 } |
|
83 else |
|
84 { |
|
85 u.iAddr8[0] &= 0xFE; |
|
86 } |
|
87 } |
|
88 |
|
89 EXPORT_C void TE64Addr::SetUniversalBit(TBool aBit) |
|
90 { |
|
91 __ASSERT_DEBUG(aBit == 0 || aBit == 1, EuiPanic(EEuiPanicBitIsNotBit)); |
|
92 |
|
93 // 0 0 0 1 1 2 .. |
|
94 // |0 7 8 5 6 3|.. |
|
95 // +----+----+----+----+----+----+ |
|
96 // |cccc|ccug|cccc|cccc|cccc|cccc|.. |
|
97 // +----+----+----+----+----+----+ |
|
98 |
|
99 if (aBit) |
|
100 { |
|
101 u.iAddr8[0] |= 0x2; |
|
102 } |
|
103 else |
|
104 { |
|
105 u.iAddr8[0] &= 0xFD; |
|
106 } |
|
107 } |
|
108 |
|
109 EXPORT_C void TE64Addr::SetAddrZero() |
|
110 { |
|
111 Mem::FillZ(AddrPtr(), AddrLen()); |
|
112 } |
|
113 |
|
114 EXPORT_C void TE64Addr::SetAddrRandom() |
|
115 { |
|
116 TTime now; |
|
117 |
|
118 #ifndef EUI_PSEUDORANDOM |
|
119 now.UniversalTime(); |
|
120 #endif |
|
121 |
|
122 TInt64 seed = now.Int64(); |
|
123 u.iAddr32[0] = Math::Rand(seed); |
|
124 u.iAddr32[1] = Math::Rand(seed); |
|
125 SetUniversalBit(0); |
|
126 SetGroupBit(0); |
|
127 } |
|
128 |
|
129 EXPORT_C void TE64Addr::SetAddrRandomNZ() |
|
130 { |
|
131 do { |
|
132 SetAddrRandom(); |
|
133 } |
|
134 while (IsZero()); |
|
135 } |
|
136 |
|
137 EXPORT_C void TE64Addr::SetAddrRandomNZButNot(const TE64Addr& aAddr) |
|
138 { |
|
139 do { |
|
140 SetAddrRandomNZ(); |
|
141 } |
|
142 while (Match(aAddr)); |
|
143 } |
|
144 |
|
145 // Really should define TE48Addr for this... -tom |
|
146 |
|
147 EXPORT_C void TE64Addr::SetAddrFromEUI48(const TUint8* aPtr) |
|
148 { |
|
149 u.iAddr8[0] = aPtr[0]; |
|
150 u.iAddr8[1] = aPtr[1]; |
|
151 u.iAddr8[2] = aPtr[2]; |
|
152 u.iAddr8[3] = 0xff; |
|
153 u.iAddr8[4] = 0xfe; |
|
154 u.iAddr8[5] = aPtr[3]; |
|
155 u.iAddr8[6] = aPtr[4]; |
|
156 u.iAddr8[7] = aPtr[5]; |
|
157 |
|
158 // The following is really not part of EUI-64 standard |
|
159 // but required for IPv6 when forming an IPv6 interface |
|
160 // identifier from an EUI-64 adderss. See RFC-2464, |
|
161 // RFC-2373. Probably the stack should do this instead. -tom |
|
162 |
|
163 // > It is required that the "u" bit (universal/local bit |
|
164 // > in IEEE EUI-64 terminology) be inverted when forming |
|
165 // > the interface identifier from the EUI-64. The "u" bit |
|
166 // > is set to one (1) to indicate global scope, and it is |
|
167 // > set to zero (0) to indicate local scope. |
|
168 |
|
169 // So at this moment the address complies EUI-64 |
|
170 |
|
171 SetUniversalBit(!IsUniversal()); |
|
172 |
|
173 // Now it doesn't, but complies to IPv6 an interface identifier |
|
174 } |
|
175 |
|
176 EXPORT_C TBool TE64Addr::Match(const TE64Addr& aAddr) const |
|
177 { |
|
178 return Mem::Compare(AddrPtrC(), AddrLen(), aAddr.AddrPtrC(), AddrLen()) ? 0 : 1; |
|
179 } |
|
180 |
|
181 EXPORT_C TBool TE64Addr::IsZero() const |
|
182 { |
|
183 return (u.iAddr32[0] == 0) && (u.iAddr32[1] == 0); |
|
184 } |
|
185 |
|
186 EXPORT_C TBool TE64Addr::IsGroup() const |
|
187 { |
|
188 return (u.iAddr8[0] & 0x1); |
|
189 } |
|
190 |
|
191 EXPORT_C TBool TE64Addr::IsUniversal() const |
|
192 { |
|
193 return (u.iAddr8[0] & 0x2); |
|
194 } |
|
195 |
|
196 EXPORT_C void TE64Addr::Output(TDes& aBuf) const |
|
197 { |
|
198 TPtrC8 e64Addr(AddrPtrC(), AddrLen()); |
|
199 TUint i; |
|
200 |
|
201 for (i = 0; i < AddrLen(); i++) |
|
202 { |
|
203 if (i) { |
|
204 aBuf.Append(':'); |
|
205 } |
|
206 |
|
207 aBuf.AppendNum(TUint(e64Addr[i]), EHex); |
|
208 } |
|
209 } |
|
210 |
|
211 EXPORT_C TUint TE64Addr::AddrLen() |
|
212 { |
|
213 return sizeof(TE64Addr); |
|
214 } |
|
215 |
|
216 EXPORT_C TUint8* TE64Addr::AddrPtr() |
|
217 { |
|
218 return &u.iAddr8[0]; |
|
219 } |
|
220 |
|
221 EXPORT_C const TUint8* TE64Addr::AddrPtrC() const |
|
222 { |
|
223 return &u.iAddr8[0]; |
|
224 } |
|
225 |
|
226 EXPORT_C TEui64Addr::TEui64Addr() : TSockAddr() |
|
227 { |
|
228 Init(); |
|
229 Address().SetAddrZero(); |
|
230 } |
|
231 |
|
232 EXPORT_C TEui64Addr::TEui64Addr(const TSockAddr& aAddr) : TSockAddr() |
|
233 { |
|
234 __ASSERT_ALWAYS(aAddr.Family() == KAfEui64 || aAddr.Family() == 0, EuiPanic(EEuiPanicFamilyMismatch)); |
|
235 Init(); |
|
236 SetAddress(TEui64Addr::Cast(aAddr).Address()); |
|
237 } |
|
238 |
|
239 EXPORT_C void TEui64Addr::Init() |
|
240 { |
|
241 SetFamily(KAfEui64); |
|
242 SetPort(0); |
|
243 SetUserLen(AddrLen()); |
|
244 } |
|
245 |
|
246 EXPORT_C void TEui64Addr::SetAddress(const TE64Addr& aAddr) |
|
247 { |
|
248 Address().SetAddr(aAddr); |
|
249 } |
|
250 |
|
251 EXPORT_C TE64Addr& TEui64Addr::Address() const |
|
252 { |
|
253 return AddrPtr()->iAddr; |
|
254 } |
|
255 |
|
256 EXPORT_C TBool TEui64Addr::Match(const TEui64Addr& aAddr) const |
|
257 { |
|
258 return Address().Match(aAddr.Address()); |
|
259 } |
|
260 |
|
261 EXPORT_C TBool TEui64Addr::IsZero() const |
|
262 { |
|
263 return Address().IsZero(); |
|
264 } |
|
265 |
|
266 EXPORT_C TEui64Addr& TEui64Addr::Cast(const TSockAddr& aAddr) |
|
267 { |
|
268 return *((TEui64Addr*)&aAddr); //lint !e1773 // standard way to implement Cast |
|
269 } |
|
270 |
|
271 EXPORT_C TEui64Addr& TEui64Addr::Cast(const TSockAddr* aAddr) |
|
272 { |
|
273 return *((TEui64Addr*)aAddr); //lint !e1773 // standard way to implement Cast |
|
274 } |
|
275 |
|
276 EXPORT_C SE64Addr* TEui64Addr::AddrPtr() const |
|
277 { |
|
278 return (SE64Addr*)UserPtr(); |
|
279 } |
|
280 |
|
281 EXPORT_C TUint TEui64Addr::AddrLen() |
|
282 { |
|
283 return TE64Addr::AddrLen(); |
|
284 } |