|
1 /* |
|
2 * Copyright (c) 2002-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: Implements IPv6 bearer |
|
15 * |
|
16 */ |
|
17 |
|
18 /* |
|
19 * %version: 11 % |
|
20 */ |
|
21 |
|
22 #include <in_sock.h> // Header is retained, but in_sock.h is modified for ipv6 |
|
23 #include <in6_if.h> |
|
24 #include <in_pkt.h> |
|
25 #include <comms-infras/connectionsettings.h> |
|
26 #include "CLanIp6Bearer.h" |
|
27 #include "WlanProto.h" |
|
28 #include <comms-infras/es_protbinder.h> |
|
29 #include "WlanProvision.h" |
|
30 |
|
31 // From Wlan |
|
32 #include <arp_hdr.h> |
|
33 #include "am_debug.h" |
|
34 #include "rwlmserver.h" |
|
35 |
|
36 // Avoiding a warning in armv5 urel |
|
37 #ifdef _DEBUG |
|
38 _LIT(KCLanIp6BearerName,"EthWlan6"); |
|
39 #endif /* _DEBUG */ |
|
40 |
|
41 using namespace ESock; |
|
42 |
|
43 // ----------------------------------------------------------------------------- |
|
44 // CLanIp6Bearer::ConstructL |
|
45 // ----------------------------------------------------------------------------- |
|
46 // |
|
47 void CLanIp6Bearer::ConstructL() |
|
48 { |
|
49 DEBUG("CLanIp6Bearer::ConstructL()"); |
|
50 |
|
51 iIfName.Format(_L("wlan6[0x%08x]"), this); |
|
52 UpdateMACAddr(); |
|
53 // ReadCommDbLanSettingsL() moved from here to point when provisioning information received |
|
54 } |
|
55 |
|
56 // ----------------------------------------------------------------------------- |
|
57 // CLanIp6Bearer::Control |
|
58 // ----------------------------------------------------------------------------- |
|
59 // |
|
60 TInt CLanIp6Bearer::Control(TUint aLevel,TUint aName,TDes8& aOption) |
|
61 { |
|
62 DEBUG("CLanIp6Bearer::Control()"); |
|
63 |
|
64 if ((aLevel==KCOLInterface) || (aLevel==KSOLInterface)) |
|
65 { |
|
66 switch (aName) |
|
67 { |
|
68 case KSoIfHardwareAddr: |
|
69 { |
|
70 typedef TPckgBuf<TSoIfHardwareAddr> THwAddr; |
|
71 THwAddr& theHwAddrRef = static_cast<THwAddr&>(aOption); |
|
72 theHwAddrRef().iHardwareAddr.SetFamily(1); |
|
73 theHwAddrRef().iHardwareAddr.SetPort(KArpHarwareType_ETHERNET); |
|
74 theHwAddrRef().iHardwareAddr.SetLength(sizeof(SSockAddr)); |
|
75 theHwAddrRef().iHardwareAddr.Append(Link()->MacAddress()); |
|
76 return KErrNone; |
|
77 } |
|
78 default: |
|
79 break; |
|
80 } |
|
81 } |
|
82 |
|
83 else if (aLevel==KSolInetIp) |
|
84 { |
|
85 switch (aName) |
|
86 { |
|
87 case KSoIp6LeaveGroup: |
|
88 case KSoIp6JoinGroup: |
|
89 { |
|
90 |
|
91 // Convert multicast IPv6 address to multicast MAC address |
|
92 TIp6Mreq& opt = *(TIp6Mreq*)aOption.Ptr(); |
|
93 TUint8* tmp = opt.iAddr.u.iAddr8; |
|
94 TMacAddress mac; |
|
95 mac.iMacAddress[0] = 0x33; |
|
96 mac.iMacAddress[1] = 0x33; |
|
97 mac.iMacAddress[2] = tmp[12]; |
|
98 mac.iMacAddress[3] = tmp[13]; |
|
99 mac.iMacAddress[4] = tmp[14]; |
|
100 mac.iMacAddress[5] = tmp[15]; |
|
101 |
|
102 TIp6Addr addr6 = opt.iAddr; |
|
103 TInetAddr addr(addr6, 0); |
|
104 TBuf<KCommsDbSvrMaxFieldLength> aa; |
|
105 addr.Output(aa); |
|
106 |
|
107 if(aName == KSoIp6JoinGroup) |
|
108 DEBUG1("CLanIp6Bearer::Control() - joining multicast address:%S", &aa); |
|
109 else |
|
110 DEBUG1("CLanIp6Bearer::Control() - leaving multicast address:%S", &aa); |
|
111 |
|
112 TInt ret = KErrNone; |
|
113 RWLMServer wlmServer; |
|
114 ret = wlmServer.Connect(); |
|
115 if( ret ) |
|
116 { |
|
117 DEBUG1("CLanIp6Bearer::Control()- ERROR connecting RWlmServer: %d", ret); |
|
118 return ret; |
|
119 } |
|
120 else |
|
121 { |
|
122 ret = wlmServer.ConfigureMulticast( aName, mac ); |
|
123 wlmServer.Close(); |
|
124 return KErrNone; |
|
125 } |
|
126 } |
|
127 default: |
|
128 break; |
|
129 } |
|
130 } |
|
131 return KErrNotSupported; |
|
132 } |
|
133 |
|
134 // ----------------------------------------------------------------------------- |
|
135 // CLanIp6Bearer::ResolveMulticastIp6 |
|
136 // ----------------------------------------------------------------------------- |
|
137 // |
|
138 void CLanIp6Bearer::ResolveMulticastIp6(TDes8& aDstAddr, RMBufChain& aPdu) |
|
139 { |
|
140 // We need to obtain the IPv6 header - i.e. the destination address. |
|
141 // Octets 12 to 15 of the destination address, should be copied to |
|
142 // Octets 2 to 5 of the aDstAddr. |
|
143 // Octets 0 and 1 should be 0x3333. |
|
144 |
|
145 DEBUG("CLanIp6Bearer::ResolveMulticastIp6()"); |
|
146 |
|
147 const TUint8 KMulticastPrefix[2] = {0x33, 0x33}; |
|
148 |
|
149 TIpv6Header* header = (TIpv6Header*)aPdu.First()->Next()->Ptr(); |
|
150 |
|
151 TUint ix; |
|
152 for(ix=0; ix<2; ix++) |
|
153 { |
|
154 aDstAddr[ix]=KMulticastPrefix[ix]; |
|
155 } |
|
156 for(ix=2; ix<6; ix++) |
|
157 { |
|
158 aDstAddr[ix]=header->iDestAddrB[ix+10]; |
|
159 } |
|
160 } |
|
161 |
|
162 // ----------------------------------------------------------------------------- |
|
163 // CLanIp6Bearer::Send |
|
164 // ----------------------------------------------------------------------------- |
|
165 // |
|
166 MLowerDataSender::TSendResult CLanIp6Bearer::Send(RMBufChain& aPdu) |
|
167 { |
|
168 // Check that we are allowed to send data |
|
169 if (!Link()->BearerIsActive(this)) |
|
170 { |
|
171 aPdu.Free(); |
|
172 return ESendBlocked; |
|
173 } |
|
174 |
|
175 RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPdu); |
|
176 TUint32 family = info->iDstAddr.Family(); |
|
177 __ASSERT_DEBUG(family!=KAfInet, User::Panic(KCLanIp6BearerName, 0)); |
|
178 |
|
179 TBuf8<KMACByteLength> destAddr; |
|
180 destAddr.SetMax(); |
|
181 |
|
182 if(family == KAfInet6) |
|
183 { |
|
184 // Only multicast packets come here with address family KAfInet6, |
|
185 // generate the ethernet address as described in RFC 2464, section 7. |
|
186 ResolveMulticastIp6(destAddr, aPdu); |
|
187 } |
|
188 else if(family == 1) |
|
189 { |
|
190 // Address family == 1, ethernet address is found from info |
|
191 destAddr.Copy(info->iDstAddr.Mid(sizeof(SSockAddr), KMACByteLength)); |
|
192 } |
|
193 else |
|
194 { |
|
195 aPdu.Free(); |
|
196 return static_cast<MLowerDataSender::TSendResult>(1); |
|
197 } |
|
198 |
|
199 return static_cast<MLowerDataSender::TSendResult>(Link()->FrameSend(aPdu,destAddr,KIP6FrameType)); |
|
200 } |
|
201 |
|
202 |
|
203 // ----------------------------------------------------------------------------- |
|
204 // CLanIp6Bearer::WantsProtocol |
|
205 // ----------------------------------------------------------------------------- |
|
206 // |
|
207 TBool CLanIp6Bearer::WantsProtocol(TUint16 aProtocolCode,const TUint8* aPayload) |
|
208 { |
|
209 DEBUG("CLanIp6Bearer::WantsProtocol()"); |
|
210 |
|
211 return (aProtocolCode==KIP6FrameType && (aPayload[0]>>4)==KIP6Protocol) ? ETrue:EFalse; |
|
212 } |
|
213 |
|
214 // ----------------------------------------------------------------------------- |
|
215 // CLanIp6Bearer::Process |
|
216 // ----------------------------------------------------------------------------- |
|
217 // |
|
218 void CLanIp6Bearer::Process(RMBufChain& aPdu) |
|
219 { |
|
220 DEBUG("CLanIp6Bearer::Process()"); |
|
221 |
|
222 if(iUpperReceiver) |
|
223 { |
|
224 iUpperReceiver->Process(aPdu); |
|
225 } |
|
226 else |
|
227 { |
|
228 aPdu.Free(); |
|
229 } |
|
230 } |
|
231 // ----------------------------------------------------------------------------- |
|
232 // CLanIp6Bearer::UpdateMACAddr |
|
233 // ----------------------------------------------------------------------------- |
|
234 // |
|
235 void CLanIp6Bearer::UpdateMACAddr() |
|
236 { |
|
237 DEBUG("CLanIp6Bearer::UpdateMACAddr()"); |
|
238 |
|
239 TE64Addr myEuMac; |
|
240 myEuMac.SetAddrFromEUI48(Link()->MacAddress().Ptr()); |
|
241 iEuiMac.SetAddress(myEuMac); |
|
242 } |
|
243 |
|
244 // ----------------------------------------------------------------------------- |
|
245 // CLanIp6Bearer::ReadCommDbLanSettingsL |
|
246 // ----------------------------------------------------------------------------- |
|
247 // |
|
248 void CLanIp6Bearer::ReadCommDbLanSettingsL() |
|
249 { |
|
250 DEBUG("CLanIp6Bearer::ReadCommDbLanSettingsL()"); |
|
251 |
|
252 ASSERT(iProvision); |
|
253 iPrimaryDns = iProvision->PrimaryDns(); |
|
254 iSecondaryDns = iProvision->SecondaryDns(); |
|
255 } |
|
256 |
|
257 // ----------------------------------------------------------------------------- |
|
258 // CLanIp6Bearer::GetConfig |
|
259 // ----------------------------------------------------------------------------- |
|
260 // |
|
261 TInt CLanIp6Bearer::GetConfig(TBinderConfig& aConfig) |
|
262 { |
|
263 DEBUG("CLanIp6Bearer::GetConfig()"); |
|
264 |
|
265 TBinderConfig6& config = static_cast<TBinderConfig6&>(aConfig); |
|
266 |
|
267 config.iFamily = KAfInet6; |
|
268 |
|
269 config.iInfo.iFeatures = KIfNeedsND | KIfCanMulticast; |
|
270 config.iInfo.iMtu = Link()->Mtu(); |
|
271 config.iInfo.iRMtu = Link()->Mtu(); |
|
272 config.iInfo.iSpeedMetric = Link()->SpeedMetric(); |
|
273 |
|
274 TEui64Addr& localId = TEui64Addr::Cast(config.iLocalId); |
|
275 localId = iEuiMac; |
|
276 |
|
277 // If required, configure static DNS addresses |
|
278 |
|
279 if (!iPrimaryDns.IsUnspecified()) |
|
280 { |
|
281 config.iNameSer1.SetAddress(iPrimaryDns); |
|
282 if (!iSecondaryDns.IsUnspecified()) |
|
283 config.iNameSer2.SetAddress(iSecondaryDns); |
|
284 } |
|
285 |
|
286 return KErrNone; |
|
287 } |
|
288 |
|
289 // ----------------------------------------------------------------------------- |
|
290 // CLanIp6Bearer::ProtocolName |
|
291 // ----------------------------------------------------------------------------- |
|
292 // |
|
293 const TDesC8& CLanIp6Bearer::ProtocolName() const |
|
294 /** |
|
295 Return the protocol name of this bearer |
|
296 |
|
297 Called from CLANLinkCommon |
|
298 */ |
|
299 { |
|
300 DEBUG("CLanIp6Bearer::ProtocolName()"); |
|
301 |
|
302 _LIT8(KProtocolName, "ip6"); |
|
303 return KProtocolName(); |
|
304 } |
|
305 // ----------------------------------------------------------------------------- |
|
306 // CLanIp6Bearer::SetProvisionL |
|
307 // ----------------------------------------------------------------------------- |
|
308 // |
|
309 void CLanIp6Bearer::SetProvisionL(const Meta::SMetaData* aProvision) |
|
310 { |
|
311 DEBUG("CLanIp6Bearer::SetProvisionL()"); |
|
312 |
|
313 if (iProvision == NULL) |
|
314 { |
|
315 iProvision = static_cast<const TLanIp6Provision*>(aProvision); |
|
316 ReadCommDbLanSettingsL(); |
|
317 } |
|
318 } |
|
319 |