|
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 // Implements the DHCP statemachine helper functions |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file DHCPStateMachine.cpp |
|
20 @internalTechnology |
|
21 */ |
|
22 |
|
23 #include "DHCPStates.h" |
|
24 #include "DHCPStatesDebug.h" |
|
25 #include "DHCPControl.h" |
|
26 #include "ExpireTimer.h" |
|
27 #include "DHCPMsg.h" |
|
28 #include <e32math.h> |
|
29 #include "DHCPServer.h" |
|
30 #include "in6_opt.h" |
|
31 #include "es_sock.h" |
|
32 |
|
33 CDHCPStateMachine::~CDHCPStateMachine() |
|
34 /** |
|
35 * Destructor of the If base class |
|
36 * |
|
37 * @internalTechnology |
|
38 * |
|
39 */ |
|
40 { |
|
41 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::~CDHCPStateMachine"))); |
|
42 Cancel(); |
|
43 delete iDhcpMessage; |
|
44 delete iMessageSender; |
|
45 delete iTimer; |
|
46 delete iHostName; |
|
47 delete iDomainName; |
|
48 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS |
|
49 iSavedExtraParameters.Close(); |
|
50 #endif //SYMBIAN_NETWORKING_DHCP_MSG_HEADERS |
|
51 iClientId.Close(); |
|
52 iSocket.Close(); |
|
53 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
54 iSvrSocket.Close(); |
|
55 delete iDNSInformation; |
|
56 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
57 } |
|
58 |
|
59 void CDHCPStateMachine::ConstructL() |
|
60 /** |
|
61 * Creates socket and connections for the object |
|
62 * |
|
63 * |
|
64 * @internalTechnology |
|
65 * |
|
66 */ |
|
67 { |
|
68 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::ConstructL"))); |
|
69 |
|
70 #ifdef _DEBUG |
|
71 // let's set debug properties to something |
|
72 // so they can be read immediately.. |
|
73 CDHCPStateMachine* const & iStateMachine = this; |
|
74 CDHCPStateMachine* const & iDhcpStateMachine = iStateMachine; |
|
75 DHCP_DEBUG_PUBLISH_READY(DHCPDebug::ENotReady); |
|
76 DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EStateUnknown); |
|
77 #endif |
|
78 |
|
79 iTimer = CExpireTimer::NewL(); |
|
80 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
81 if(!iServerImpl) // Assemble client Ids only for DHCP client implementation |
|
82 { |
|
83 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
84 InitialiseSocketL(); |
|
85 AssembleClientIDsL(); |
|
86 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
87 } |
|
88 else |
|
89 InitialiseServerSocketL(); |
|
90 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
91 } |
|
92 |
|
93 void CDHCPStateMachine::Start(MStateMachineNotify* aStateMachineNotify) |
|
94 /** |
|
95 * The Start function |
|
96 * |
|
97 * Starts the statemachine task |
|
98 * |
|
99 * @internalTechnology |
|
100 */ |
|
101 { |
|
102 SetLastError( KErrNone ); |
|
103 iReceiving = EFalse; |
|
104 iHistory = 0; |
|
105 SetActiveEvent(iFirstState); |
|
106 if ( !aStateMachineNotify ) |
|
107 {//no notifier specified => leave the current one unchanged |
|
108 aStateMachineNotify = iStateMachineNotify; |
|
109 } |
|
110 CStateMachine::Start(NULL, NULL, aStateMachineNotify); |
|
111 } |
|
112 |
|
113 void CDHCPStateMachine::CloseNSendMsgL(TRequestStatus& aStatus, CDHCPStateMachine::EAddressType aEAddressType) |
|
114 /** |
|
115 * Handles sending of packets for this object |
|
116 * |
|
117 * @internalTechnology |
|
118 * |
|
119 */ |
|
120 { |
|
121 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::CloseNSendMsgL"))); |
|
122 PrepareToSendL(aEAddressType); |
|
123 iMessageSender->Cancel(); |
|
124 |
|
125 GetServerAddress(iSocketAddr); |
|
126 AddScopeToAddrL(iSocketAddr); |
|
127 |
|
128 #ifdef _DEBUG |
|
129 THostName addrDes; |
|
130 iSocketAddr.Output(addrDes); |
|
131 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, |
|
132 _L("CDHCPStateMachine::CloseNSendMsgL - Sending message to %S%%%d"), &addrDes, iSocketAddr.Scope())); |
|
133 #endif |
|
134 |
|
135 iSocket.SendTo(iDhcpMessage->Message(), iSocketAddr, 0, aStatus); |
|
136 } |
|
137 |
|
138 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
139 void CDHCPStateMachine::CloseNSendServerMsgL(TRequestStatus& aStatus, CDHCPStateMachine::EAddressType aEAddressType) |
|
140 /** |
|
141 * Handles sending of packets for this object |
|
142 * |
|
143 * @internalTechnology |
|
144 * |
|
145 */ |
|
146 { |
|
147 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::CloseNSendMsgL"))); |
|
148 |
|
149 |
|
150 PrepareToSendServerMsgL(aEAddressType); |
|
151 iMessageSender->Cancel(); |
|
152 |
|
153 GetClientAddress(iSrvSocketAddr); |
|
154 AddScopeToClientAddrL(iSrvSocketAddr); |
|
155 |
|
156 #ifdef _DEBUG |
|
157 THostName addrDes; |
|
158 iSrvSocketAddr.Output(addrDes); |
|
159 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, |
|
160 _L("CDHCPStateMachine::CloseNSendServerMsgL - Sending message to %S%%%d"), &addrDes, iSrvSocketAddr.Scope())); |
|
161 #endif |
|
162 |
|
163 iSvrSocket.SendTo(iDhcpMessage->Message(), iSrvSocketAddr, 0, aStatus); |
|
164 } |
|
165 |
|
166 void CDHCPStateMachine::GetClientAddress( TInetAddr& /*aAddress*/ ) |
|
167 /** |
|
168 * GetClientAddress |
|
169 * |
|
170 * Null implementation |
|
171 * |
|
172 * @internalTechnology |
|
173 */ |
|
174 { |
|
175 } |
|
176 |
|
177 #ifdef SYMBIAN_DNS_PROXY |
|
178 TInetAddr CDHCPStateMachine::GetListenerAddress() |
|
179 { |
|
180 return iCurrentAddress; |
|
181 } |
|
182 #endif |
|
183 |
|
184 void CDHCPStateMachine::InitServerStateMachineL(MStateMachineNotify* /*aStateMachineNotify*/) |
|
185 /** |
|
186 * InitServerStateMachineL |
|
187 * |
|
188 * Null implementation |
|
189 * |
|
190 * @internalTechnology |
|
191 */ |
|
192 { |
|
193 } |
|
194 |
|
195 void CDHCPStateMachine::InitServerBinding(MStateMachineNotify* /*aStateMachineNotify*/) |
|
196 { |
|
197 |
|
198 } |
|
199 |
|
200 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
201 |
|
202 void CDHCPStateMachine::CloseNSendMsgL(TTimeIntervalSeconds aSecs, TInt aMaxRetryCount, CDHCPStateMachine::EAddressType aEAddressType) |
|
203 /** |
|
204 * Handles sending of packets for this object |
|
205 * |
|
206 * @internalTechnology |
|
207 * |
|
208 */ |
|
209 { |
|
210 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::CloseNSendMsgL"))); |
|
211 PrepareToSendL(aEAddressType); |
|
212 iMessageSender->Cancel(); |
|
213 |
|
214 TInetAddr addr; |
|
215 GetServerAddress( addr ); |
|
216 AddScopeToAddrL(addr); |
|
217 |
|
218 #ifdef _DEBUG |
|
219 THostName addrDes; |
|
220 addr.Output(addrDes); |
|
221 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, |
|
222 _L("CDHCPStateMachine::CloseNSendMsgL - Sending message to %S%%%d"), &addrDes, addr.Scope())); |
|
223 #endif |
|
224 |
|
225 if (FastTimeoutDuringInform()) // true only when InformNegotiationIsRequiredForConnectionStartCompletion is ETrue |
|
226 { |
|
227 iMessageSender->SendL(addr, iDhcpMessage->Message(), (aSecs.Int() * KMicrosecondsInSecs) / 14, aMaxRetryCount); |
|
228 } |
|
229 else |
|
230 { |
|
231 iMessageSender->SendL(addr, iDhcpMessage->Message(), aSecs.Int() * KMicrosecondsInSecs, aMaxRetryCount); |
|
232 } |
|
233 } |
|
234 |
|
235 TInt CDHCPStateMachine::MSReportError(TInt aError) |
|
236 /** |
|
237 * Report an error properly |
|
238 * |
|
239 * @internalTechnology |
|
240 */ |
|
241 { |
|
242 Cancel(); |
|
243 |
|
244 SetLastError(aError); |
|
245 OnCompletion(); |
|
246 |
|
247 return aError; |
|
248 } |
|
249 |
|
250 void CDHCPStateMachine::Cancel() |
|
251 /** |
|
252 * Cancel the state machine's activities |
|
253 * |
|
254 * @internalTechnology |
|
255 */ |
|
256 { |
|
257 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::Cancel"))); |
|
258 CancelMessageSender(); |
|
259 iSocket.Close(); |
|
260 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
261 iSvrSocket.Close(); |
|
262 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
263 CancelTimer(); |
|
264 CStateMachine::Cancel(KErrNone); |
|
265 delete iFirstState; |
|
266 iFirstState = NULL; |
|
267 iFastTimeout = EFalse; // reset iFastTimeout |
|
268 iMaxRetryCount = KInfinity;//reset |
|
269 } |
|
270 |
|
271 void CDHCPStateMachine::DoCancel() |
|
272 /** |
|
273 * Implements a default docancel for the connection object |
|
274 * |
|
275 * @internalTechnology |
|
276 */ |
|
277 { |
|
278 // we have to cancel send and recv independently as cancelAll() |
|
279 // doesn't satisfy us, only supporting read, write, ioctl, connect, |
|
280 // accept and shutdown...:-( |
|
281 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::DoCancel"))); |
|
282 if (iSocket.SubSessionHandle()) |
|
283 { |
|
284 // check that the socket is open |
|
285 // and if it is then we need to cancel things on it |
|
286 iSocket.CancelRecv(); |
|
287 } |
|
288 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
289 if(iSvrSocket.SubSessionHandle()) |
|
290 { |
|
291 iSvrSocket.CancelRecv(); |
|
292 } |
|
293 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
294 /* iAsyncCancelHandler is set by the DHCP State that assumes ownership of the |
|
295 RequestStatus object of CDHCPStateMachine |
|
296 */ |
|
297 if(iAsyncCancelHandler) |
|
298 { |
|
299 iAsyncCancelHandler->Cancel(); |
|
300 } |
|
301 } |
|
302 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
303 void CDHCPStateMachine::FetchServerAddressL() |
|
304 /** |
|
305 * This function is used to get the server's address (interface address) |
|
306 * |
|
307 */ |
|
308 { |
|
309 if(!iSvrSocket.SubSessionHandle()) |
|
310 InitialiseServerSocketL(); |
|
311 |
|
312 TPckgBuf<TSoInetInterfaceInfo> opt; |
|
313 while (iSvrSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) |
|
314 { |
|
315 if (opt().iName == iInterfaceName) |
|
316 { |
|
317 iCurrentAddress = opt().iAddress; |
|
318 break; |
|
319 } |
|
320 } |
|
321 } |
|
322 |
|
323 void CDHCPStateMachine::SetDNSInformation(TDes8* aDNSInfo) |
|
324 { |
|
325 delete iDNSInformation; |
|
326 iDNSInformation = NULL; |
|
327 |
|
328 iDNSInformation = HBufC8::NewL(aDNSInfo->Length()); |
|
329 iDNSInformation->Des() = *aDNSInfo; |
|
330 } |
|
331 |
|
332 TBool CDHCPStateMachine::CheckNetworkId() |
|
333 /** |
|
334 * This function compares the NetworkIds of the client and server |
|
335 * |
|
336 */ |
|
337 { |
|
338 iInformClientAddr.SetV4MappedAddress(iCiaddr); |
|
339 |
|
340 if ((iInformClientAddr.Address() & KInetAddrNetMaskC) == |
|
341 (iCurrentAddress.Address() & KInetAddrNetMaskC)) |
|
342 { |
|
343 return ETrue; |
|
344 } |
|
345 else |
|
346 { |
|
347 return EFalse; |
|
348 } |
|
349 } |
|
350 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
351 |
|
352 void CDHCPStateMachine::FetchHWAddress() |
|
353 /** |
|
354 * Fetches hardware address from the interface |
|
355 * |
|
356 */ |
|
357 { |
|
358 TPckgBuf<TSoInetInterfaceInfo> opt; |
|
359 while (iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) |
|
360 { |
|
361 if (opt().iName == iInterfaceName) |
|
362 { |
|
363 iHardwareAddr = opt().iHwAddr; |
|
364 if(iHardwareAddr.Length() <= KHwAddrOffset) |
|
365 { |
|
366 // the hardware address came back too short |
|
367 // to be a valid TSockAddr.. so we'll treat it as an empty value |
|
368 iHardwareAddr.SetFamily(KAFUnspec); |
|
369 iHardwareAddr.SetLength(KHwAddrOffset); |
|
370 } |
|
371 break; |
|
372 } |
|
373 } |
|
374 } |
|
375 |
|
376 |
|
377 void CDHCPStateMachine::StartTimer(TTimeIntervalSeconds aSeconds, MExpireTimer& aExpireTimer) |
|
378 /** |
|
379 * Give the tcp/ip6 stack time to perform |
|
380 * its gratuitous ARP... |
|
381 * |
|
382 * @internalTechnology |
|
383 */ |
|
384 { |
|
385 CancelTimer(); |
|
386 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::StartTimerL"))); |
|
387 |
|
388 iTimer->After(aSeconds, aExpireTimer); |
|
389 } |
|
390 |
|
391 void CDHCPStateMachine::StartTimer( TTimeIntervalMicroSeconds32 aMicroSeconds, MExpireTimer& aExpireTimer) |
|
392 /** |
|
393 * Give the tcp/ip6 stack time to perform |
|
394 * its gratuitous ARP... |
|
395 * |
|
396 * @internalTechnology |
|
397 */ |
|
398 { |
|
399 CancelTimer(); |
|
400 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::StartTimerL"))); |
|
401 |
|
402 iTimer->After(aMicroSeconds, aExpireTimer); |
|
403 } |
|
404 |
|
405 void CDHCPStateMachine::RemoveConfiguredAddress( const TSoInet6InterfaceInfo& aSoInet6InterfaceInfo ) |
|
406 /** |
|
407 * This function can be called as a result of DAD failing |
|
408 * or the lease expiring! It removes the address from the interface |
|
409 * inside the TCP/IP6 stack as the address cannot continue to be used. |
|
410 * |
|
411 * @see "Implementation of IPv4/IPv6 Basic Socket API for Symbian OS" |
|
412 * document for explanation of TSoInet6InterfaceInfo and its use |
|
413 * @internalTechnology |
|
414 */ |
|
415 { |
|
416 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::RemoveConfiguredAddress"))); |
|
417 |
|
418 TPckgBuf<TSoInet6InterfaceInfo> configInfo(aSoInet6InterfaceInfo); |
|
419 // not interested in error |
|
420 // how could we attempt to handle it anyway?...keep trying??? i think not... |
|
421 // ensure that we have a socket to write down |
|
422 iSocket.Close(); |
|
423 (void)iSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection); |
|
424 (void)iSocket.SetOpt(KSoInetConfigInterface, KSolInetIfCtrl, configInfo); |
|
425 // make socket invisible for interface counting |
|
426 (void)iSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0); |
|
427 } |
|
428 |
|
429 void CDHCPStateMachine::ConfigureInterfaceL( const TSoInet6InterfaceInfo& aInterfaceInfo ) |
|
430 /** |
|
431 * Set the interface IP address and other params |
|
432 * into the TCP/IP6 stack. |
|
433 * |
|
434 * What we set depends on the setup |
|
435 * in commDB for the service. If ipAddressFromServer |
|
436 * is true then we set the ip address that has |
|
437 * been assigned by DHCP, along with the netmask and gateway. |
|
438 * If ipAddressFromServer is false, then we set the static ip |
|
439 * address as long as it has been okayed by the DHCP server after |
|
440 * we have sent an inform. We will then set the netmask and gateway |
|
441 * choosing from those in commDB if they have been given values, or |
|
442 * those returned in the DHCP Server ACK if a zero address is in commDB |
|
443 * The same principle applies to DNS Server addresses. |
|
444 * |
|
445 * @internalTechnology |
|
446 */ |
|
447 { |
|
448 |
|
449 TPckgBuf<TSoInet6InterfaceInfo> configInfo(aInterfaceInfo); |
|
450 |
|
451 |
|
452 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::ConfigureInterfaceL - KSoInetConfigInterface"))); |
|
453 |
|
454 User::LeaveIfError(iSocket.SetOpt(KSoInetConfigInterface, KSolInetIfCtrl, configInfo)); |
|
455 } |
|
456 |
|
457 TInt CDHCPStateMachine::BindToSource() |
|
458 /** |
|
459 * Binds socket to newly assigned address for the interface |
|
460 * |
|
461 * @internalTechnology |
|
462 */ |
|
463 { |
|
464 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::BindToSourceL"))); |
|
465 iSocket.Close(); // destroy the old socket |
|
466 |
|
467 UpdateHistory(CDHCPState::EBindToSource); |
|
468 // now start a new one. |
|
469 // might be nice if we left here if the socket open fails...but nobody's perfect... |
|
470 // PS: cannot leave here the failure doesn't mean exception here see the usage.... |
|
471 TInt err = iSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection); |
|
472 // make socket invisable for interface counting |
|
473 if (err == KErrNone) |
|
474 { |
|
475 err = iSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0); |
|
476 } |
|
477 |
|
478 if (err == KErrNone) //PDEF122482: Enabling the ReUseAddr option. |
|
479 { |
|
480 err = iSocket.SetOpt(KSoReuseAddr, KSolInetIp, 1); |
|
481 } |
|
482 |
|
483 if (err == KErrNone) |
|
484 { |
|
485 TInetAddr bindTo; |
|
486 AssignAddresses( bindTo, iCurrentAddress ); |
|
487 |
|
488 err = iSocket.Bind(bindTo); |
|
489 if (err==KErrNone) |
|
490 { |
|
491 // we are finished with this socket, |
|
492 // release it so as not to hold esock open |
|
493 iSocket.Close(); |
|
494 } |
|
495 } |
|
496 return err; |
|
497 } |
|
498 |
|
499 |
|
500 TUint32 CDHCPStateMachine::GetNetworkIdL() const |
|
501 { |
|
502 TUint32 networkId; |
|
503 _LIT(KIapNetwork, "IAP\\IAPNetwork"); |
|
504 User::LeaveIfError(iConnection.GetIntSetting(KIapNetwork, networkId)); |
|
505 |
|
506 return networkId; |
|
507 } |
|
508 |
|
509 void CDHCPStateMachine::AddScopeToAddrL(TInetAddr& addr) |
|
510 { |
|
511 TPckgBuf<TSoInetIfQuery> queryBuf; |
|
512 queryBuf().iName = iInterfaceName; |
|
513 User::LeaveIfError(iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, queryBuf)); |
|
514 |
|
515 const TUint s = addr.Ip6Address().Scope() - 1; |
|
516 |
|
517 if (s < 16) |
|
518 { |
|
519 addr.SetScope(queryBuf().iZone[s]); |
|
520 } |
|
521 } |
|
522 |
|
523 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
524 void CDHCPStateMachine::AddScopeToClientAddrL(TInetAddr& addr) |
|
525 { |
|
526 TPckgBuf<TSoInetIfQuery> queryBuf; |
|
527 queryBuf().iName = iInterfaceName; |
|
528 User::LeaveIfError(iSvrSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, queryBuf)); |
|
529 |
|
530 const TUint s = addr.Ip6Address().Scope() - 1; |
|
531 |
|
532 if (s < 16) |
|
533 { |
|
534 addr.SetScope(queryBuf().iZone[s]); |
|
535 } |
|
536 } |
|
537 // Set when the DHCP server implementation is being used |
|
538 void CDHCPStateMachine::SetServerState(TBool aServerImpl) |
|
539 { |
|
540 iServerImpl = aServerImpl; |
|
541 } |
|
542 |
|
543 TInt CDHCPStateMachine::BindServerInterface() |
|
544 /** |
|
545 * Binds socket to newly assigned address for the interface |
|
546 * |
|
547 * @internalTechnology |
|
548 */ |
|
549 { |
|
550 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::BindServerInterface"))); |
|
551 iSvrSocket.Close(); // destroy the old socket |
|
552 |
|
553 // now start a new one. |
|
554 TInt err = iSvrSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection); |
|
555 // make socket invisable for interface counting |
|
556 if (err == KErrNone) |
|
557 { |
|
558 TInt err = iSvrSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0); |
|
559 } |
|
560 |
|
561 if (err == KErrNone) |
|
562 { |
|
563 TInetAddr bindTo; |
|
564 AssignAddresses( bindTo, iCurrentAddress ); |
|
565 err = iSvrSocket.Bind(bindTo); |
|
566 } |
|
567 return err; |
|
568 } |
|
569 |
|
570 |
|
571 TInetAddr CDHCPStateMachine::GetInterfaceServerGlobalAddress() |
|
572 /** |
|
573 * Are any of the addresses on the interface global addresses? |
|
574 * If so, DHCP might decide not to attempt to discover an address. |
|
575 * |
|
576 * Returns unspecified address if no global address present. |
|
577 */ |
|
578 { |
|
579 TPckgBuf<TSoInetInterfaceInfo> opt; |
|
580 if (iSvrSocket.SubSessionHandle() == 0) |
|
581 { |
|
582 InitialiseServerSocketL(); |
|
583 } |
|
584 iSvrSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
|
585 __CFLOG_STMT(TBuf<512> addrStr;); |
|
586 while (iSvrSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) |
|
587 { |
|
588 if (opt().iName == iInterfaceName) |
|
589 { |
|
590 TInetAddr& addr = opt().iAddress; |
|
591 __CFLOG_STMT(addr.Output(addrStr);); |
|
592 if ( ! addr.IsLinkLocal()) |
|
593 { |
|
594 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L("Global address %S found on interface %S"),&addrStr,&iInterfaceName)); |
|
595 return addr; |
|
596 } |
|
597 else |
|
598 { |
|
599 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L("Linklocal address %S found on interface %S"),&addrStr,&iInterfaceName)); |
|
600 } |
|
601 break; |
|
602 } |
|
603 } |
|
604 return TInetAddr(); // unspecified |
|
605 } |
|
606 |
|
607 |
|
608 |
|
609 |
|
610 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
611 |
|
612 TInetAddr CDHCPStateMachine::GetInterfaceGlobalAddress() |
|
613 /** |
|
614 * Are any of the addresses on the interface global addresses? |
|
615 * If so, DHCP might decide not to attempt to discover an address. |
|
616 * |
|
617 * Returns unspecified address if no global address present. |
|
618 */ |
|
619 { |
|
620 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
621 if(iServerImpl) |
|
622 { |
|
623 return GetInterfaceServerGlobalAddress(); |
|
624 } |
|
625 else |
|
626 { |
|
627 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
628 |
|
629 TPckgBuf<TSoInetInterfaceInfo> opt; |
|
630 if (iSocket.SubSessionHandle() == 0) |
|
631 { |
|
632 InitialiseSocketL(); |
|
633 } |
|
634 iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
|
635 __CFLOG_STMT(TBuf<512> addrStr;); |
|
636 while (iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) |
|
637 { |
|
638 if (opt().iName == iInterfaceName) |
|
639 { |
|
640 TInetAddr& addr = opt().iAddress; |
|
641 __CFLOG_STMT(addr.Output(addrStr);); |
|
642 if ( ! addr.IsLinkLocal()) |
|
643 { |
|
644 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L("Global address %S found on interface %S"),&addrStr,&iInterfaceName)); |
|
645 return addr; |
|
646 } |
|
647 else |
|
648 { |
|
649 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L("Linklocal address %S found on interface %S"),&addrStr,&iInterfaceName)); |
|
650 } |
|
651 break; |
|
652 } |
|
653 } |
|
654 return TInetAddr(); // unspecified |
|
655 |
|
656 #ifdef SYMBIAN_NETWORKING_DHCPSERVER |
|
657 } |
|
658 #endif // SYMBIAN_NETWORKING_DHCPSERVER |
|
659 } |
|
660 |
|
661 |
|
662 TBool CDHCPStateMachine::DoesInterfaceKnowAnyDNSServers() |
|
663 /** |
|
664 * Does the interface know of any DNS servers? |
|
665 */ |
|
666 { |
|
667 TPckgBuf<TSoInetInterfaceInfo> opt; |
|
668 if (iSocket.SubSessionHandle() == 0) |
|
669 { |
|
670 InitialiseSocketL(); |
|
671 } |
|
672 iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
|
673 __CFLOG_STMT(TBuf<512> addrStr;); |
|
674 while (iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) |
|
675 { |
|
676 if (opt().iName == iInterfaceName) |
|
677 { |
|
678 TInetAddr& addr = opt().iNameSer1; |
|
679 __CFLOG_STMT(addr.Output(addrStr);); |
|
680 if ( ! addr.IsUnspecified() ) |
|
681 { |
|
682 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L("DNS server %S found on interface %S"),&addrStr,&iInterfaceName)); |
|
683 return ETrue; |
|
684 } |
|
685 else |
|
686 { |
|
687 __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L("No DNS servers already set on interface %S (prior to DHCP)"),&iInterfaceName)); |
|
688 } |
|
689 break; |
|
690 } |
|
691 } |
|
692 return EFalse; |
|
693 } |
|
694 |
|
695 |
|
696 |
|
697 |
|
698 TDhcpRnd::TDhcpRnd():iXid(0) |
|
699 /** |
|
700 * Constructor for this little random number |
|
701 * class that creates us a random transaction id |
|
702 * |
|
703 * @internalTechnology |
|
704 */ |
|
705 { |
|
706 TTime now; |
|
707 now.HomeTime(); |
|
708 iSeed = now.Int64(); |
|
709 } |
|
710 |
|
711 TInt TDhcpRnd::Rnd(TInt aMin, TInt aMax) |
|
712 /** |
|
713 * Utility class function to generated a real |
|
714 * random number |
|
715 * |
|
716 * @internalTechnology |
|
717 */ |
|
718 { |
|
719 return Math::Rand(iSeed)%(aMax-aMin+1)+aMin; |
|
720 } |