VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/DHCP/Config.cpp@ 49245

最後變更 在這個檔案從49245是 49065,由 vboxsync 提交於 11 年 前

VBoxNetDHCP: Congig.cpp warning [-Wunused-parameter]

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 23.3 KB
 
1/* $Id: Config.cpp 49065 2013-10-12 07:19:24Z vboxsync $ */
2
3/**
4 * XXX: license.
5 */
6
7#include <iprt/asm.h>
8#include <iprt/net.h>
9#include <iprt/time.h>
10
11#include <VBox/sup.h>
12#include <VBox/intnet.h>
13#include <VBox/intnetinline.h>
14#include <VBox/vmm/vmm.h>
15#include <VBox/version.h>
16
17#include "../NetLib/VBoxNetLib.h"
18
19#include <list>
20#include <vector>
21#include <map>
22#include <string>
23
24#include "Config.h"
25
26/* types */
27class Lease::Data
28{
29public:
30 Data()
31 {
32 m_address.u = 0;
33 m_client = NULL;
34 fBinding = true;
35 u64TimestampBindingStarted = 0;
36 u64TimestampLeasingStarted = 0;
37 u32LeaseExpirationPeriod = 0;
38 u32BindExpirationPeriod = 0;
39 pCfg = NULL;
40
41 }
42 ~Data(){}
43
44 RTNETADDRIPV4 m_address;
45
46 /** lease isn't commited */
47 bool fBinding;
48
49 /** Timestamp when lease commited. */
50 uint64_t u64TimestampLeasingStarted;
51 /** Period when lease is expired in secs. */
52 uint32_t u32LeaseExpirationPeriod;
53
54 /** timestamp when lease was bound */
55 uint64_t u64TimestampBindingStarted;
56 /* Period when binding is expired in secs. */
57 uint32_t u32BindExpirationPeriod;
58
59 NetworkConfigEntity *pCfg;
60 Client *m_client;
61};
62
63
64/* consts */
65
66const NullConfigEntity *g_NullConfig = new NullConfigEntity();
67RootConfigEntity *g_RootConfig = new RootConfigEntity(std::string("ROOT"), 1200 /* 20 min. */);
68const ClientMatchCriteria *g_AnyClient = new AnyClientMatchCriteria();
69
70static ConfigurationManager *g_ConfigurationManager = ConfigurationManager::getConfigurationManager();
71
72static NetworkManager *g_NetworkManager = NetworkManager::getNetworkManager();
73
74int BaseConfigEntity::match(Client& client, BaseConfigEntity **cfg)
75{
76 int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0);
77 if (m_children.empty())
78 {
79 if (iMatch > 0)
80 {
81 *cfg = this;
82 return iMatch;
83 }
84 }
85 else
86 {
87 *cfg = this;
88 /* XXX: hack */
89 BaseConfigEntity *matching = this;
90 int matchingLevel = m_MatchLevel;
91
92 for (std::vector<BaseConfigEntity *>::iterator it = m_children.begin();
93 it != m_children.end();
94 ++it)
95 {
96 iMatch = (*it)->match(client, &matching);
97 if (iMatch > matchingLevel)
98 {
99 *cfg = matching;
100 matchingLevel = iMatch;
101 }
102 }
103 return matchingLevel;
104 }
105 return iMatch;
106}
107
108/* Client */
109
110Client::Client(const RTMAC& mac)
111{
112 m_mac = mac;
113 m_lease = NULL;
114}
115
116/* Configs
117 NetworkConfigEntity(std::string name,
118 ConfigEntity* pCfg,
119 ClientMatchCriteria* criteria,
120 RTNETADDRIPV4& networkID,
121 RTNETADDRIPV4& networkMask)
122*/
123static const RTNETADDRIPV4 g_AnyIpv4 = {0};
124static const RTNETADDRIPV4 g_AllIpv4 = {0xffffffff};
125RootConfigEntity::RootConfigEntity(std::string name, uint32_t expPeriod):
126 NetworkConfigEntity(name, g_NullConfig, g_AnyClient, g_AnyIpv4, g_AllIpv4)
127{
128 m_MatchLevel = 2;
129 m_u32ExpirationPeriod = expPeriod;
130}
131
132
133/* Configuration Manager */
134ConfigurationManager *ConfigurationManager::getConfigurationManager()
135{
136 if (!g_ConfigurationManager)
137 g_ConfigurationManager = new ConfigurationManager();
138
139 return g_ConfigurationManager;
140}
141
142
143int ConfigurationManager::extractRequestList(PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& rawOpt)
144{
145 return ConfigurationManager::findOption(RTNET_DHCP_OPT_PARAM_REQ_LIST, pDhcpMsg, cbDhcpMsg, rawOpt);
146}
147
148
149Client *ConfigurationManager::getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg)
150{
151
152 VecClientIterator it;
153 bool fDhcpValid = false;
154 uint8_t uMsgType = 0;
155
156 fDhcpValid = RTNetIPv4IsDHCPValid(NULL, pDhcpMsg, cbDhcpMsg, &uMsgType);
157 AssertReturn(fDhcpValid, NULL);
158
159 LogFlowFunc(("dhcp:mac:%RTmac\n", &pDhcpMsg->bp_chaddr.Mac));
160 /* 1st. client IDs */
161 for ( it = m_clients.begin();
162 it != m_clients.end();
163 ++it)
164 {
165 if (*(*it) == pDhcpMsg->bp_chaddr.Mac)
166 {
167 LogFlowFunc(("client:mac:%RTmac\n", &(*it)->m_mac));
168 /* check timestamp that request wasn't expired. */
169 return (*it);
170 }
171 }
172
173 if (it == m_clients.end())
174 {
175 /* We hasn't got any session for this client */
176 m_clients.push_back(new Client(pDhcpMsg->bp_chaddr.Mac));
177 return m_clients.back();
178 }
179
180 return NULL;
181}
182
183/**
184 * Finds an option.
185 *
186 * @returns On success, a pointer to the first byte in the option data (no none
187 * then it'll be the byte following the 0 size field) and *pcbOpt set
188 * to the option length.
189 * On failure, NULL is returned and *pcbOpt unchanged.
190 *
191 * @param uOption The option to search for.
192 * @param pDhcpMsg The DHCP message.
193 * that this is adjusted if the option length is larger
194 * than the message buffer.
195 */
196int
197ConfigurationManager::findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt)
198{
199 Assert(uOption != RTNET_DHCP_OPT_PAD);
200
201 /*
202 * Validate the DHCP bits and figure the max size of the options in the vendor field.
203 */
204 if (cbDhcpMsg <= RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts))
205 return VERR_INVALID_PARAMETER;
206
207 if (pDhcpMsg->bp_vend.Dhcp.dhcp_cookie != RT_H2N_U32_C(RTNET_DHCP_COOKIE))
208 return VERR_INVALID_PARAMETER;
209
210 size_t cbLeft = cbDhcpMsg - RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts);
211 if (cbLeft > RTNET_DHCP_OPT_SIZE)
212 cbLeft = RTNET_DHCP_OPT_SIZE;
213
214 /*
215 * Search the vendor field.
216 */
217 bool fExtended = false;
218 uint8_t const *pb = &pDhcpMsg->bp_vend.Dhcp.dhcp_opts[0];
219 while (pb && cbLeft > 0)
220 {
221 uint8_t uCur = *pb;
222 if (uCur == RTNET_DHCP_OPT_PAD)
223 {
224 cbLeft--;
225 pb++;
226 }
227 else if (cbLeft <= 1)
228 break;
229 else
230 {
231 size_t cbCur = pb[1];
232 if (cbCur > cbLeft - 2)
233 cbCur = cbLeft - 2;
234 if (uCur == uOption)
235 {
236 opt.u8OptId = uCur;
237 memcpy(opt.au8RawOpt, pb+2, cbCur);
238 opt.cbRawOpt = cbCur;
239 return VINF_SUCCESS;
240 }
241 pb += cbCur + 2;
242 cbLeft -= cbCur - 2;
243 }
244 }
245
246 /** @todo search extended dhcp option field(s) when present */
247
248 return VERR_NOT_FOUND;
249}
250
251
252/**
253 * We bind lease for client till it continue with it on DHCPREQUEST.
254 */
255Lease *ConfigurationManager::allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg)
256{
257 /**
258 * Well, session hasn't get the config.
259 */
260 AssertPtrReturn(client, NULL);
261
262 /**
263 * This mean that client has already bound or commited lease.
264 * If we've it happens it means that we received DHCPDISCOVER twice.
265 */
266 if (client->m_lease)
267 {
268 if (client->m_lease->isExpired())
269 expireLease4Client(client);
270 else
271 {
272 AssertReturn(client->m_lease->getAddress().u != 0,NULL);
273 return client->m_lease;
274 }
275 }
276
277 RTNETADDRIPV4 hintAddress;
278 RawOption opt;
279 Lease *please = NULL;
280
281 NetworkConfigEntity *pNetCfg;
282
283 AssertReturn(g_RootConfig->match(*client, (BaseConfigEntity **)&pNetCfg) > 0, NULL);
284
285 /* DHCPDISCOVER MAY contain request address */
286 hintAddress.u = 0;
287 int rc = findOption(RTNET_DHCP_OPT_REQ_ADDR, pDhcpMsg, cbDhcpMsg, opt);
288 if (RT_SUCCESS(rc))
289 {
290 hintAddress.u = *(uint32_t *)opt.au8RawOpt;
291 if ( RT_H2N_U32(hintAddress.u) < RT_H2N_U32(pNetCfg->lowerIp().u)
292 || RT_H2N_U32(hintAddress.u) > RT_H2N_U32(pNetCfg->upperIp().u))
293 hintAddress.u = 0; /* clear hint */
294 }
295
296 if ( hintAddress.u
297 && !isAddressTaken(hintAddress, NULL))
298 {
299 please = new Lease();
300 please->init();
301 please->setConfig(pNetCfg);
302 please->setClient(client);
303 client->m_lease = please;
304 client->m_lease->setAddress(hintAddress);
305 m_allocations[please] = hintAddress;
306 return please;
307 }
308
309 uint32_t u32 = 0;
310 for(u32 = RT_H2N_U32(pNetCfg->lowerIp().u);
311 u32 <= RT_H2N_U32(pNetCfg->upperIp().u);
312 ++u32)
313 {
314 RTNETADDRIPV4 address;
315 address.u = RT_H2N_U32(u32);
316 if (!isAddressTaken(address, NULL))
317 {
318 please = new Lease();
319 please->init();
320 please->setConfig(pNetCfg);
321 please->setClient(client);
322 please->setAddress(address);
323
324 client->m_lease = please;
325
326 m_allocations[please] = address;
327 return please;
328 }
329 }
330
331 return NULL;
332}
333
334
335int ConfigurationManager::commitLease4Client(Client *client)
336{
337 client->m_lease->bindingPhase(false);
338
339 client->m_lease->setExpiration(client->m_lease->getConfig()->expirationPeriod());
340 client->m_lease->phaseStart(RTTimeMilliTS());
341
342 return VINF_SUCCESS;
343}
344
345int ConfigurationManager::expireLease4Client(Client *client)
346{
347 MapLease2Ip4AddressIterator it = m_allocations.find(client->m_lease);
348 AssertReturn(it != m_allocations.end(), VERR_NOT_FOUND);
349
350 m_allocations.erase(it);
351
352 delete client->m_lease;
353 client->m_lease = NULL;
354
355 return VINF_SUCCESS;
356}
357
358bool ConfigurationManager::isAddressTaken(const RTNETADDRIPV4& addr, Lease** ppLease)
359{
360 MapLease2Ip4AddressIterator it;
361
362 for (it = m_allocations.begin();
363 it != m_allocations.end();
364 ++it)
365 {
366 if (it->second.u == addr.u)
367 {
368 if (ppLease)
369 *ppLease = it->first;
370
371 return true;
372 }
373 }
374 return false;
375}
376
377NetworkConfigEntity *ConfigurationManager::addNetwork(NetworkConfigEntity *,
378 const RTNETADDRIPV4& networkId,
379 const RTNETADDRIPV4& netmask,
380 RTNETADDRIPV4& LowerAddress,
381 RTNETADDRIPV4& UpperAddress)
382{
383 static int id;
384 char name[64];
385
386 RTStrPrintf(name, RT_ELEMENTS(name), "network-%d", id);
387 std::string strname(name);
388 id++;
389
390
391 if (!LowerAddress.u)
392 LowerAddress = networkId;
393
394 if (!UpperAddress.u)
395 UpperAddress.u = networkId.u | (~netmask.u);
396
397 return new NetworkConfigEntity(strname,
398 g_RootConfig,
399 g_AnyClient,
400 5,
401 networkId,
402 netmask,
403 LowerAddress,
404 UpperAddress);
405}
406
407HostConfigEntity *ConfigurationManager::addHost(NetworkConfigEntity* pCfg,
408 const RTNETADDRIPV4& address,
409 ClientMatchCriteria *criteria)
410{
411 static int id;
412 char name[64];
413
414 RTStrPrintf(name, RT_ELEMENTS(name), "host-%d", id);
415 std::string strname(name);
416 id++;
417
418 return new HostConfigEntity(address, strname, pCfg, criteria);
419}
420
421int ConfigurationManager::addToAddressList(uint8_t u8OptId, RTNETADDRIPV4& address)
422{
423 switch(u8OptId)
424 {
425 case RTNET_DHCP_OPT_DNS:
426 m_nameservers.push_back(address);
427 break;
428 case RTNET_DHCP_OPT_ROUTERS:
429 m_routers.push_back(address);
430 break;
431 default:
432 Log(("dhcp-opt: list (%d) unsupported\n", u8OptId));
433 }
434 return VINF_SUCCESS;
435}
436
437int ConfigurationManager::flushAddressList(uint8_t u8OptId)
438{
439 switch(u8OptId)
440 {
441 case RTNET_DHCP_OPT_DNS:
442 m_nameservers.clear();
443 break;
444 case RTNET_DHCP_OPT_ROUTERS:
445 m_routers.clear();
446 break;
447 default:
448 Log(("dhcp-opt: list (%d) unsupported\n", u8OptId));
449 }
450 return VINF_SUCCESS;
451}
452
453const Ipv4AddressContainer& ConfigurationManager::getAddressList(uint8_t u8OptId)
454{
455 switch(u8OptId)
456 {
457 case RTNET_DHCP_OPT_DNS:
458 return m_nameservers;
459
460 case RTNET_DHCP_OPT_ROUTERS:
461 return m_routers;
462
463 }
464 /* XXX: Grrr !!! */
465 return m_empty;
466}
467
468int ConfigurationManager::setString(uint8_t u8OptId, const std::string& str)
469{
470 switch (u8OptId)
471 {
472 case RTNET_DHCP_OPT_DOMAIN_NAME:
473 m_domainName = str;
474 break;
475 default:
476 break;
477 }
478
479 return VINF_SUCCESS;
480}
481
482const std::string& ConfigurationManager::getString(uint8_t u8OptId)
483{
484 switch (u8OptId)
485 {
486 case RTNET_DHCP_OPT_DOMAIN_NAME:
487 if (m_domainName.length())
488 return m_domainName;
489 else
490 return m_noString;
491 default:
492 break;
493 }
494
495 return m_noString;
496}
497
498/**
499 * Network manager
500 */
501NetworkManager *NetworkManager::getNetworkManager()
502{
503 if (!g_NetworkManager)
504 g_NetworkManager = new NetworkManager();
505
506 return g_NetworkManager;
507}
508
509
510/**
511 * Network manager creates DHCPOFFER datagramm
512 */
513int NetworkManager::offer4Client(Client *client, uint32_t u32Xid,
514 uint8_t *pu8ReqList, int cReqList)
515{
516 AssertPtrReturn(client, VERR_INTERNAL_ERROR);
517 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
518
519 prepareReplyPacket4Client(client, u32Xid);
520
521
522 RTNETADDRIPV4 address = client->m_lease->getAddress();
523 BootPReplyMsg.BootPHeader.bp_yiaddr = address;
524
525 /* Ubuntu ???*/
526 BootPReplyMsg.BootPHeader.bp_ciaddr = address;
527
528 /* options:
529 * - IP lease time
530 * - message type
531 * - server identifier
532 */
533 RawOption opt;
534 RT_ZERO(opt);
535
536 /* XXX: can't store options per session */
537 AssertPtr(client);
538
539 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE;
540 opt.au8RawOpt[0] = RTNET_DHCP_MT_OFFER;
541 opt.cbRawOpt = 1;
542 client->rawOptions.push_back(opt);
543
544 opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME;
545 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->getConfig()->expirationPeriod());
546 opt.cbRawOpt = sizeof(RTNETADDRIPV4);
547 client->rawOptions.push_back(opt);
548
549 processParameterReqList(client, pu8ReqList, cReqList);
550
551 return doReply(client);
552}
553
554
555/**
556 * Network manager creates DHCPACK
557 */
558int NetworkManager::ack(Client *client, uint32_t u32Xid,
559 uint8_t *pu8ReqList, int cReqList)
560{
561 AssertPtrReturn(client, VERR_INTERNAL_ERROR);
562 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
563
564 RTNETADDRIPV4 address;
565
566 prepareReplyPacket4Client(client, u32Xid);
567
568 address = client->m_lease->getAddress();
569 BootPReplyMsg.BootPHeader.bp_ciaddr = address;
570
571
572 /* rfc2131 4.3.1 is about DHCPDISCOVER and this value is equal to ciaddr from
573 * DHCPREQUEST or 0 ...
574 * XXX: Using addressHint is not correct way to initialize [cy]iaddress...
575 */
576 BootPReplyMsg.BootPHeader.bp_ciaddr = address;
577 BootPReplyMsg.BootPHeader.bp_yiaddr = address;
578
579 Assert(BootPReplyMsg.BootPHeader.bp_yiaddr.u);
580
581 /* options:
582 * - IP address lease time (if DHCPREQUEST)
583 * - message type
584 * - server identifier
585 */
586 RawOption opt;
587 RT_ZERO(opt);
588
589 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE;
590 opt.au8RawOpt[0] = RTNET_DHCP_MT_ACK;
591 opt.cbRawOpt = 1;
592 client->rawOptions.push_back(opt);
593
594 /*
595 * XXX: lease time should be conditional. If on dhcprequest then tim should be provided,
596 * else on dhcpinform it mustn't.
597 */
598 opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME;
599 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->getExpiration());
600 opt.cbRawOpt = sizeof(RTNETADDRIPV4);
601 client->rawOptions.push_back(opt);
602
603 processParameterReqList(client, pu8ReqList, cReqList);
604
605 return doReply(client);
606}
607
608
609/**
610 * Network manager creates DHCPNAK
611 */
612int NetworkManager::nak(Client* client, uint32_t u32Xid)
613{
614 AssertPtrReturn(client, VERR_INTERNAL_ERROR);
615
616 if (!client->m_lease)
617 return VERR_INTERNAL_ERROR;
618
619 prepareReplyPacket4Client(client, u32Xid);
620
621 /* this field filed in prepareReplyPacket4Session, and
622 * RFC 2131 require to have it zero fo NAK.
623 */
624 BootPReplyMsg.BootPHeader.bp_yiaddr.u = 0;
625
626 /* options:
627 * - message type (if DHCPREQUEST)
628 * - server identifier
629 */
630 RawOption opt;
631 RT_ZERO(opt);
632
633 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE;
634 opt.au8RawOpt[0] = RTNET_DHCP_MT_NAC;
635 opt.cbRawOpt = 1;
636 client->rawOptions.push_back(opt);
637
638 return doReply(client);
639}
640
641
642/**
643 *
644 */
645int NetworkManager::prepareReplyPacket4Client(Client *client, uint32_t u32Xid)
646{
647 AssertPtrReturn(client, VERR_INTERNAL_ERROR);
648 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
649
650 memset(&BootPReplyMsg, 0, sizeof(BootPReplyMsg));
651
652 BootPReplyMsg.BootPHeader.bp_op = RTNETBOOTP_OP_REPLY;
653 BootPReplyMsg.BootPHeader.bp_htype = RTNET_ARP_ETHER;
654 BootPReplyMsg.BootPHeader.bp_hlen = sizeof(RTMAC);
655 BootPReplyMsg.BootPHeader.bp_hops = 0;
656 BootPReplyMsg.BootPHeader.bp_xid = u32Xid;
657 BootPReplyMsg.BootPHeader.bp_secs = 0;
658 /* XXX: bp_flags should be processed specially */
659 BootPReplyMsg.BootPHeader.bp_flags = 0;
660 BootPReplyMsg.BootPHeader.bp_ciaddr.u = 0;
661 BootPReplyMsg.BootPHeader.bp_giaddr.u = 0;
662
663 BootPReplyMsg.BootPHeader.bp_chaddr.Mac = client->m_mac;
664
665 BootPReplyMsg.BootPHeader.bp_yiaddr = client->m_lease->getAddress();
666 BootPReplyMsg.BootPHeader.bp_siaddr.u = 0;
667
668
669 BootPReplyMsg.BootPHeader.bp_vend.Dhcp.dhcp_cookie = RT_H2N_U32_C(RTNET_DHCP_COOKIE);
670
671 memset(&BootPReplyMsg.BootPHeader.bp_vend.Dhcp.dhcp_opts[0],
672 '\0',
673 RTNET_DHCP_OPT_SIZE);
674
675 return VINF_SUCCESS;
676}
677
678
679int NetworkManager::doReply(Client *client)
680{
681 int rc;
682
683 AssertPtrReturn(client, VERR_INTERNAL_ERROR);
684 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);
685
686 /*
687 Options....
688 */
689 VBoxNetDhcpWriteCursor Cursor(&BootPReplyMsg.BootPHeader, RTNET_DHCP_NORMAL_SIZE);
690
691 /* The basics */
692
693 Cursor.optIPv4Addr(RTNET_DHCP_OPT_SERVER_ID, m_OurAddress);
694
695 while(!client->rawOptions.empty())
696 {
697 RawOption opt = client->rawOptions.back();
698 if (!Cursor.begin(opt.u8OptId, opt.cbRawOpt))
699 break;
700 Cursor.put(opt.au8RawOpt, opt.cbRawOpt);
701
702 client->rawOptions.pop_back();
703 }
704
705
706 if (!client->rawOptions.empty())
707 {
708 Log(("Wasn't able to put all options\n"));
709 /* force clean up */
710 client->rawOptions.clear();
711 }
712
713 Cursor.optEnd();
714
715 /*
716 */
717#if 0
718 if (!(pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)) /** @todo need to see someone set this flag to check that it's correct. */
719 {
720 rc = VBoxNetUDPUnicast(m_pSession,
721 m_hIf,
722 m_pIfBuf,
723 m_OurAddress,
724 &m_OurMac,
725 RTNETIPV4_PORT_BOOTPS, /* sender */
726 IPv4AddrBrdCast,
727 &BootPReplyMsg.BootPHeader->bp_chaddr.Mac,
728 RTNETIPV4_PORT_BOOTPC, /* receiver */
729 &BootPReplyMsg, cbBooPReplyMsg);
730 }
731 else
732#endif
733 rc = VBoxNetUDPBroadcast(m_pSession,
734 m_hIf,
735 m_pIfBuf,
736 m_OurAddress,
737 &m_OurMac,
738 RTNETIPV4_PORT_BOOTPS, /* sender */
739 RTNETIPV4_PORT_BOOTPC,
740 &BootPReplyMsg, RTNET_DHCP_NORMAL_SIZE);
741
742 AssertRCReturn(rc,rc);
743
744 return VINF_SUCCESS;
745}
746
747
748int NetworkManager::processParameterReqList(Client* client, uint8_t *pu8ReqList, int cReqList)
749{
750 /* request parameter list */
751 RawOption opt;
752 int idxParam = 0;
753
754 AssertPtrReturn(client, VERR_INTERNAL_ERROR);
755
756 uint8_t *pReqList = pu8ReqList;
757
758 const NetworkConfigEntity *pNetCfg = client->m_lease->getConfig();
759
760 for (idxParam = 0; idxParam < cReqList; ++idxParam)
761 {
762
763 RT_ZERO(opt);
764 opt.u8OptId = pReqList[idxParam];
765 switch(pReqList[idxParam])
766 {
767 case RTNET_DHCP_OPT_SUBNET_MASK:
768 ((PRTNETADDRIPV4)opt.au8RawOpt)->u = pNetCfg->netmask().u;
769 opt.cbRawOpt = sizeof(RTNETADDRIPV4);
770 client->rawOptions.push_back(opt);
771 break;
772
773 case RTNET_DHCP_OPT_ROUTERS:
774 case RTNET_DHCP_OPT_DNS:
775 {
776 const Ipv4AddressContainer lst =
777 g_ConfigurationManager->getAddressList(pReqList[idxParam]);
778 PRTNETADDRIPV4 pAddresses = (PRTNETADDRIPV4)&opt.au8RawOpt[0];
779
780 for (Ipv4AddressConstIterator it = lst.begin();
781 it != lst.end();
782 ++it)
783 {
784 *pAddresses = (*it);
785 pAddresses++;
786 opt.cbRawOpt += sizeof(RTNETADDRIPV4);
787 }
788
789 if (!lst.empty())
790 client->rawOptions.push_back(opt);
791 }
792 break;
793 case RTNET_DHCP_OPT_DOMAIN_NAME:
794 {
795 std::string domainName = g_ConfigurationManager->getString(pReqList[idxParam]);
796 if (domainName == g_ConfigurationManager->m_noString)
797 break;
798
799 char *pszDomainName = (char *)&opt.au8RawOpt[0];
800
801 strcpy(pszDomainName, domainName.c_str());
802 opt.cbRawOpt = domainName.length();
803 client->rawOptions.push_back(opt);
804 }
805 break;
806 default:
807 Log(("opt: %d is ignored\n", pReqList[idxParam]));
808 break;
809 }
810 }
811
812 return VINF_SUCCESS;
813}
814
815
816Lease::~Lease()
817{
818 if (m)
819 delete m;
820}
821
822
823void Lease::init()
824{
825 if (!m)
826 m = new Lease::Data();
827}
828
829
830bool Lease::isExpired() const
831{
832 AssertPtrReturn(m, false);
833
834 if (!m->fBinding)
835 return (ASMDivU64ByU32RetU32(RTTimeMilliTS() - m->u64TimestampLeasingStarted, 1000)
836 > m->u32LeaseExpirationPeriod);
837 else
838 return (ASMDivU64ByU32RetU32(RTTimeMilliTS() - m->u64TimestampBindingStarted, 1000)
839 > m->u32BindExpirationPeriod);
840}
841
842
843void Lease::phaseStart(uint64_t u64Start)
844{
845 if (m->fBinding)
846 m->u64TimestampBindingStarted = u64Start;
847 else
848 m->u64TimestampLeasingStarted = u64Start;
849}
850
851
852void Lease::bindingPhase(bool fOnOff)
853{
854 m->fBinding = fOnOff;
855}
856
857
858bool Lease::isInBindingPhase() const
859{
860 return m->fBinding;
861}
862
863
864void Lease::setExpiration(uint32_t exp)
865{
866 if (m->fBinding)
867 m->u32BindExpirationPeriod = exp;
868 else
869 m->u32LeaseExpirationPeriod = exp;
870}
871
872
873uint32_t Lease::getExpiration() const
874{
875 if (m->fBinding)
876 return m->u32BindExpirationPeriod;
877 else
878 return m->u32LeaseExpirationPeriod;
879}
880
881
882RTNETADDRIPV4 Lease::getAddress() const
883{
884 return m->m_address;
885}
886
887
888void Lease::setAddress(RTNETADDRIPV4 address)
889{
890 m->m_address = address;
891}
892
893
894const NetworkConfigEntity *Lease::getConfig() const
895{
896 return m->pCfg;
897}
898
899
900void Lease::setConfig(NetworkConfigEntity *pCfg)
901{
902 m->pCfg = pCfg;
903}
904
905
906Client *Lease::getClient() const
907{
908 return m->m_client;
909}
910
911void Lease::setClient(Client *client)
912{
913 m->m_client = client;
914}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette