Changeset 79771 in vbox
- Timestamp:
- Jul 14, 2019 9:10:58 PM (6 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
r79761 r79771 202 202 203 203 /** 204 * Helper class for dhcpdHandleAddAndModify 205 */ 206 class DHCPCmdScope 207 { 208 DHCPConfigScope_T m_enmScope; 209 const char *m_pszName; 210 uint8_t m_uSlot; 211 ComPtr<IDHCPConfig> m_ptrConfig; 212 ComPtr<IDHCPGlobalConfig> m_ptrGlobalConfig; 213 ComPtr<IDHCPGroupConfig> m_ptrGroupConfig; 214 ComPtr<IDHCPIndividualConfig> m_ptrIndividualConfig; 215 216 public: 217 DHCPCmdScope() 218 : m_enmScope(DHCPConfigScope_Global) 219 , m_pszName(NULL) 220 , m_uSlot(0) 221 { 222 } 223 224 void setGlobal() 225 { 226 m_enmScope = DHCPConfigScope_Global; 227 m_pszName = NULL; 228 m_uSlot = 0; 229 resetPointers(); 230 } 231 232 void setGroup(const char *pszGroup) 233 { 234 m_enmScope = DHCPConfigScope_Group; 235 m_pszName = pszGroup; 236 m_uSlot = 0; 237 resetPointers(); 238 } 239 240 void setMachineNIC(const char *pszMachine) 241 { 242 m_enmScope = DHCPConfigScope_MachineNIC; 243 m_pszName = pszMachine; 244 m_uSlot = 0; 245 resetPointers(); 246 } 247 248 void setMachineSlot(uint8_t uSlot) 249 { 250 Assert(m_enmScope == DHCPConfigScope_MachineNIC); 251 m_uSlot = uSlot; 252 resetPointers(); 253 } 254 255 void setMACAddress(const char *pszMACAddress) 256 { 257 m_enmScope = DHCPConfigScope_MAC; 258 m_pszName = pszMACAddress; 259 m_uSlot = 0; 260 resetPointers(); 261 } 262 263 ComPtr<IDHCPConfig> &getConfig(ComPtr<IDHCPServer> const &ptrDHCPServer) 264 { 265 if (m_ptrConfig.isNull()) 266 CHECK_ERROR2I_STMT(ptrDHCPServer, GetConfig(m_enmScope, Bstr(m_pszName).raw(), m_uSlot, TRUE /*mayAdd*/, 267 m_ptrConfig.asOutParam()), m_ptrConfig.setNull()); 268 return m_ptrConfig; 269 } 270 271 ComPtr<IDHCPIndividualConfig> &getIndividual(ComPtr<IDHCPServer> const &ptrDHCPServer) 272 { 273 getConfig(ptrDHCPServer); 274 if (m_ptrIndividualConfig.isNull() && m_ptrConfig.isNotNull()) 275 { 276 HRESULT hrc = m_ptrConfig.queryInterfaceTo(m_ptrIndividualConfig.asOutParam()); 277 if (FAILED(hrc)) 278 { 279 com::GlueHandleComError(m_ptrConfig, "queryInterface", hrc, __FILE__, __LINE__); 280 m_ptrIndividualConfig.setNull(); 281 } 282 } 283 return m_ptrIndividualConfig; 284 } 285 286 ComPtr<IDHCPGroupConfig> &getGroup(ComPtr<IDHCPServer> const &ptrDHCPServer) 287 { 288 getConfig(ptrDHCPServer); 289 if (m_ptrGroupConfig.isNull() && m_ptrConfig.isNotNull()) 290 { 291 HRESULT hrc = m_ptrConfig.queryInterfaceTo(m_ptrGroupConfig.asOutParam()); 292 if (FAILED(hrc)) 293 { 294 com::GlueHandleComError(m_ptrConfig, "queryInterface", hrc, __FILE__, __LINE__); 295 m_ptrGroupConfig.setNull(); 296 } 297 } 298 return m_ptrGroupConfig; 299 } 300 301 DHCPConfigScope_T getScope() const { return m_enmScope; } 302 303 private: 304 void resetPointers() 305 { 306 m_ptrConfig.setNull(); 307 m_ptrGlobalConfig.setNull(); 308 m_ptrIndividualConfig.setNull(); 309 m_ptrGroupConfig.setNull(); 310 } 311 }; 312 313 enum 314 { 315 DHCP_ADDMOD = 1000, 316 DHCP_ADDMOD_ZAP_OPTIONS, 317 DHCP_ADDMOD_INCL_MAC, 318 DHCP_ADDMOD_EXCL_MAC, 319 DHCP_ADDMOD_DEL_MAC, 320 DHCP_ADDMOD_INCL_MAC_WILD, 321 DHCP_ADDMOD_EXCL_MAC_WILD, 322 DHCP_ADDMOD_DEL_MAC_WILD, 323 DHCP_ADDMOD_INCL_VENDOR, 324 DHCP_ADDMOD_EXCL_VENDOR, 325 DHCP_ADDMOD_DEL_VENDOR, 326 DHCP_ADDMOD_INCL_VENDOR_WILD, 327 DHCP_ADDMOD_EXCL_VENDOR_WILD, 328 DHCP_ADDMOD_DEL_VENDOR_WILD, 329 DHCP_ADDMOD_INCL_USER, 330 DHCP_ADDMOD_EXCL_USER, 331 DHCP_ADDMOD_DEL_USER, 332 DHCP_ADDMOD_INCL_USER_WILD, 333 DHCP_ADDMOD_EXCL_USER_WILD, 334 DHCP_ADDMOD_DEL_USER_WILD, 335 DHCP_ADDMOD_ZAP_CONDITIONS 336 }; 337 338 /** 204 339 * Handles the 'add' and 'modify' subcommands. 205 340 */ 206 341 static DECLCALLBACK(RTEXITCODE) dhcpdHandleAddAndModify(PDHCPDCMDCTX pCtx, int argc, char **argv) 207 342 { 208 /*209 * Parse options.210 */211 343 static const RTGETOPTDEF s_aOptions[] = 212 344 { 213 345 DHCPD_CMD_COMMON_OPTION_DEFS(), 214 { "--server-ip", 'a', RTGETOPT_REQ_STRING }, 215 { "--ip", 'a', RTGETOPT_REQ_STRING }, // deprecated 216 { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated 217 { "--netmask", 'm', RTGETOPT_REQ_STRING }, 218 { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated 219 { "--lower-ip", 'l', RTGETOPT_REQ_STRING }, 220 { "--lowerip", 'l', RTGETOPT_REQ_STRING }, 221 { "-lowerip", 'l', RTGETOPT_REQ_STRING }, // deprecated 222 { "--upper-ip", 'u', RTGETOPT_REQ_STRING }, 223 { "--upperip", 'u', RTGETOPT_REQ_STRING }, 224 { "-upperip", 'u', RTGETOPT_REQ_STRING }, // deprecated 225 { "--enable", 'e', RTGETOPT_REQ_NOTHING }, 226 { "-enable", 'e', RTGETOPT_REQ_NOTHING }, // deprecated 227 { "--disable", 'd', RTGETOPT_REQ_NOTHING }, 228 { "-disable", 'd', RTGETOPT_REQ_NOTHING }, // deprecated 229 { "--global", 'g', RTGETOPT_REQ_NOTHING }, 230 { "--vm", 'M', RTGETOPT_REQ_STRING }, 231 { "--nic", 'n', RTGETOPT_REQ_UINT8 }, 232 { "--add-opt", 'A', RTGETOPT_REQ_UINT8 }, 233 { "--del-opt", 'D', RTGETOPT_REQ_UINT8 }, 346 { "--server-ip", 'a', RTGETOPT_REQ_STRING }, 347 { "--ip", 'a', RTGETOPT_REQ_STRING }, // deprecated 348 { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated 349 { "--netmask", 'm', RTGETOPT_REQ_STRING }, 350 { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated 351 { "--lower-ip", 'l', RTGETOPT_REQ_STRING }, 352 { "--lowerip", 'l', RTGETOPT_REQ_STRING }, 353 { "-lowerip", 'l', RTGETOPT_REQ_STRING }, // deprecated 354 { "--upper-ip", 'u', RTGETOPT_REQ_STRING }, 355 { "--upperip", 'u', RTGETOPT_REQ_STRING }, 356 { "-upperip", 'u', RTGETOPT_REQ_STRING }, // deprecated 357 { "--enable", 'e', RTGETOPT_REQ_NOTHING }, 358 { "-enable", 'e', RTGETOPT_REQ_NOTHING }, // deprecated 359 { "--disable", 'd', RTGETOPT_REQ_NOTHING }, 360 { "-disable", 'd', RTGETOPT_REQ_NOTHING }, // deprecated 361 { "--global", 'g', RTGETOPT_REQ_NOTHING }, 362 { "--group", 'G', RTGETOPT_REQ_STRING }, 363 { "--mac-address", 'E', RTGETOPT_REQ_MACADDR }, 364 { "--vm", 'M', RTGETOPT_REQ_STRING }, 365 { "--nic", 'n', RTGETOPT_REQ_UINT8 }, 366 { "--set-opt", 's', RTGETOPT_REQ_UINT8 }, 367 { "--set-opt-hex", 'x', RTGETOPT_REQ_UINT8 }, 368 { "--del-opt", 'D', RTGETOPT_REQ_UINT8 }, 369 { "--zap-options", DHCP_ADDMOD_ZAP_OPTIONS, RTGETOPT_REQ_NOTHING }, 370 { "--min-lease-time", 'q' , RTGETOPT_REQ_UINT32 }, 371 { "--default-lease-time", 'L' , RTGETOPT_REQ_UINT32 }, 372 { "--max-lease-time", 'Q' , RTGETOPT_REQ_UINT32 }, 373 { "--remove-config", 'R', RTGETOPT_REQ_NOTHING }, 374 { "--fixed-address", 'f', RTGETOPT_REQ_STRING }, 375 /* group conditions: */ 376 { "--incl-mac", DHCP_ADDMOD_INCL_MAC, RTGETOPT_REQ_STRING }, 377 { "--excl-mac", DHCP_ADDMOD_EXCL_MAC, RTGETOPT_REQ_STRING }, 378 { "--del-mac", DHCP_ADDMOD_DEL_MAC, RTGETOPT_REQ_STRING }, 379 { "--incl-mac-wild", DHCP_ADDMOD_INCL_MAC_WILD, RTGETOPT_REQ_STRING }, 380 { "--excl-mac-wild", DHCP_ADDMOD_EXCL_MAC_WILD, RTGETOPT_REQ_STRING }, 381 { "--del-mac-wild", DHCP_ADDMOD_DEL_MAC_WILD, RTGETOPT_REQ_STRING }, 382 { "--incl-vendor", DHCP_ADDMOD_INCL_VENDOR, RTGETOPT_REQ_STRING }, 383 { "--excl-vendor", DHCP_ADDMOD_EXCL_VENDOR, RTGETOPT_REQ_STRING }, 384 { "--del-vendor", DHCP_ADDMOD_DEL_VENDOR, RTGETOPT_REQ_STRING }, 385 { "--incl-vendor-wild", DHCP_ADDMOD_INCL_VENDOR_WILD, RTGETOPT_REQ_STRING }, 386 { "--excl-vendor-wild", DHCP_ADDMOD_EXCL_VENDOR_WILD, RTGETOPT_REQ_STRING }, 387 { "--del-vendor-wild", DHCP_ADDMOD_DEL_VENDOR_WILD, RTGETOPT_REQ_STRING }, 388 { "--incl-user", DHCP_ADDMOD_INCL_USER, RTGETOPT_REQ_STRING }, 389 { "--excl-user", DHCP_ADDMOD_EXCL_USER, RTGETOPT_REQ_STRING }, 390 { "--del-user", DHCP_ADDMOD_DEL_USER, RTGETOPT_REQ_STRING }, 391 { "--incl-user-wild", DHCP_ADDMOD_INCL_USER_WILD, RTGETOPT_REQ_STRING }, 392 { "--excl-user-wild", DHCP_ADDMOD_EXCL_USER_WILD, RTGETOPT_REQ_STRING }, 393 { "--del-user-wild", DHCP_ADDMOD_DEL_USER_WILD, RTGETOPT_REQ_STRING }, 394 { "--zap-conditions", DHCP_ADDMOD_ZAP_CONDITIONS, RTGETOPT_REQ_NOTHING }, 395 /* obsolete, to be removed: */ 234 396 { "--id", 'i', RTGETOPT_REQ_UINT8 }, // obsolete, backwards compatibility only. 235 397 { "--value", 'p', RTGETOPT_REQ_STRING }, // obsolete, backwards compatibility only. … … 239 401 }; 240 402 241 const char *pszServerIp = NULL; 242 const char *pszNetmask = NULL; 243 const char *pszLowerIp = NULL; 244 const char *pszUpperIp = NULL; 245 int fEnabled = -1; 246 247 DhcpOpts GlobalDhcpOptions; 248 DhcpOptIds GlobalDhcpOptions2Delete; 249 VmSlot2OptionsM VmSlot2Options; 250 VmSlot2OptionIdsM VmSlot2Options2Delete; 251 252 const char *pszVmName = NULL; 253 uint8_t u8Slot = 0; 254 DhcpOpts *pScopeOptions = &GlobalDhcpOptions; 255 DhcpOptIds *pScopeOptions2Delete = &GlobalDhcpOptions2Delete; 256 257 bool fNeedValueOrRemove = false; /* Only used with --id; remove in 6.1+ */ 258 uint8_t u8OptId = 0; /* Only used too keep --id for following --value/--remove. remove in 6.1+ */ 259 260 RTGETOPTSTATE GetState; 261 int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); 262 AssertRCReturn(vrc, RTEXITCODE_FAILURE); 263 264 RTGETOPTUNION ValueUnion; 265 while ((vrc = RTGetOpt(&GetState, &ValueUnion))) 266 { 267 switch (vrc) 268 { 269 DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion); 270 case 'a': // --server-ip 271 pszServerIp = ValueUnion.psz; 272 break; 273 case 'm': // --netmask 274 pszNetmask = ValueUnion.psz; 275 break; 276 case 'l': // --lower-ip 277 pszLowerIp = ValueUnion.psz; 278 break; 279 case 'u': // --upper-ip 280 pszUpperIp = ValueUnion.psz; 281 break; 282 case 'e': // --enable 283 fEnabled = 1; 284 break; 285 case 'd': // --disable 286 fEnabled = 0; 287 break; 288 289 case 'g': // --global Sets the option scope to 'global'. 290 if (fNeedValueOrRemove) 291 return errorSyntax("Incomplete option sequence preseeding '--global'"); 292 pScopeOptions = &GlobalDhcpOptions; 293 pScopeOptions2Delete = &GlobalDhcpOptions2Delete; 294 break; 295 296 case 'M': // --vm Sets the option scope to ValueUnion.psz + 0. 297 if (fNeedValueOrRemove) 298 return errorSyntax("Incomplete option sequence preseeding '--vm'"); 299 pszVmName = ValueUnion.psz; 300 u8Slot = 0; 301 pScopeOptions = &VmSlot2Options[VmNameSlotKey(pszVmName, u8Slot)]; 302 pScopeOptions2Delete = &VmSlot2Options2Delete[VmNameSlotKey(pszVmName, u8Slot)]; 303 break; 304 305 case 'n': // --nic Sets the option scope to pszVmName + (ValueUnion.u8 - 1). 306 if (!pszVmName) 307 return errorSyntax("--nic option requires a --vm preceeding selecting the VM it should apply to"); 308 if (fNeedValueOrRemove) 309 return errorSyntax("Incomplete option sequence preseeding '--nic=%u", ValueUnion.u8); 310 u8Slot = ValueUnion.u8; 311 if (u8Slot < 1) 312 return errorSyntax("invalid NIC number: %u", u8Slot); 313 --u8Slot; 314 pScopeOptions = &VmSlot2Options[VmNameSlotKey(pszVmName, u8Slot)]; 315 pScopeOptions2Delete = &VmSlot2Options2Delete[VmNameSlotKey(pszVmName, u8Slot)]; 316 break; 317 318 case 'A': // --add-opt num hexvalue 403 /* 404 * Parse the arguments in two passes: 405 * 406 * 1. Validate the command line and establish the IDHCPServer settings. 407 * 2. Execute the various IDHCPConfig settings changes. 408 * 409 * This is considered simpler than duplicating the command line instructions 410 * into elaborate structures and executing these. 411 */ 412 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 413 ComPtr<IDHCPServer> ptrDHCPServer; 414 for (size_t iPass = 0; iPass < 2; iPass++) 415 { 416 const char *pszServerIp = NULL; 417 const char *pszNetmask = NULL; 418 const char *pszLowerIp = NULL; 419 const char *pszUpperIp = NULL; 420 int fEnabled = -1; 421 422 DHCPCmdScope Scope; 423 char szMACAddress[32]; 424 425 bool fNeedValueOrRemove = false; /* Only used with --id; remove in 6.1+ */ 426 uint8_t u8OptId = 0; /* Only used too keep --id for following --value/--remove. remove in 6.1+ */ 427 428 RTGETOPTSTATE GetState; 429 int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); 430 AssertRCReturn(vrc, RTEXITCODE_FAILURE); 431 432 RTGETOPTUNION ValueUnion; 433 while ((vrc = RTGetOpt(&GetState, &ValueUnion))) 434 { 435 switch (vrc) 319 436 { 320 uint8_t const idAddOpt = ValueUnion.u8; 321 vrc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_STRING); 322 if (RT_FAILURE(vrc)) 323 return errorFetchValue(1, "--add-opt", vrc, &ValueUnion); 324 pScopeOptions->push_back(DhcpOptSpec((DhcpOpt_T)idAddOpt, Utf8Str(ValueUnion.psz))); 325 break; 437 DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion); 438 case 'a': // --server-ip 439 pszServerIp = ValueUnion.psz; 440 break; 441 case 'm': // --netmask 442 pszNetmask = ValueUnion.psz; 443 break; 444 case 'l': // --lower-ip 445 pszLowerIp = ValueUnion.psz; 446 break; 447 case 'u': // --upper-ip 448 pszUpperIp = ValueUnion.psz; 449 break; 450 case 'e': // --enable 451 fEnabled = 1; 452 break; 453 case 'd': // --disable 454 fEnabled = 0; 455 break; 456 457 /* 458 * Configuration selection: 459 */ 460 case 'g': // --global Sets the option scope to 'global'. 461 if (fNeedValueOrRemove) 462 return errorSyntax("Incomplete option sequence preseeding '--global'"); 463 Scope.setGlobal(); 464 break; 465 466 case 'G': // --group 467 if (fNeedValueOrRemove) 468 return errorSyntax("Incomplete option sequence preseeding '--group'"); 469 if (!*ValueUnion.psz) 470 return errorSyntax("Group name cannot be empty"); 471 Scope.setGroup(ValueUnion.psz); 472 break; 473 474 case 'E': // --mac-address 475 if (fNeedValueOrRemove) 476 return errorSyntax("Incomplete option sequence preseeding '--mac-address'"); 477 RTStrPrintf(szMACAddress, sizeof(szMACAddress), "%RTmac", &ValueUnion.MacAddr); 478 Scope.setMACAddress(szMACAddress); 479 break; 480 481 case 'M': // --vm Sets the option scope to ValueUnion.psz + 0. 482 if (fNeedValueOrRemove) 483 return errorSyntax("Incomplete option sequence preseeding '--vm'"); 484 Scope.setMachineNIC(ValueUnion.psz); 485 break; 486 487 case 'n': // --nic Sets the option scope to pszVmName + (ValueUnion.u8 - 1). 488 if (Scope.getScope() != DHCPConfigScope_MachineNIC) 489 return errorSyntax("--nic option requires a --vm preceeding selecting the VM it should apply to"); 490 if (fNeedValueOrRemove) 491 return errorSyntax("Incomplete option sequence preseeding '--nic=%u", ValueUnion.u8); 492 if (ValueUnion.u8 < 1) 493 return errorSyntax("invalid NIC number: %u", ValueUnion.u8); 494 Scope.setMachineSlot(ValueUnion.u8 - 1); 495 break; 496 497 /* 498 * Modify configuration: 499 */ 500 case 's': // --set-opt num stringvalue 501 { 502 uint8_t const idAddOpt = ValueUnion.u8; 503 vrc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_STRING); 504 if (RT_FAILURE(vrc)) 505 return errorFetchValue(1, "--set-opt", vrc, &ValueUnion); 506 if (iPass == 1) 507 { 508 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 509 if (ptrConfig.isNull()) 510 return RTEXITCODE_FAILURE; 511 CHECK_ERROR2I_STMT(ptrConfig, SetOption((DhcpOpt_T)idAddOpt, DHCPOptionEncoding_Legacy, 512 Bstr(ValueUnion.psz).raw()), rcExit = RTEXITCODE_FAILURE); 513 } 514 break; 515 } 516 517 case 'x': // --set-opt-hex num hex-string 518 { 519 uint8_t const idAddOpt = ValueUnion.u8; 520 vrc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_STRING); 521 if (RT_FAILURE(vrc)) 522 return errorFetchValue(1, "--set-opt-hex", vrc, &ValueUnion); 523 uint8_t abBuf[256]; 524 size_t cbRet; 525 vrc = RTStrConvertHexBytesEx(ValueUnion.psz, abBuf, sizeof(abBuf), RTSTRCONVERTHEXBYTES_F_SEP_COLON, 526 NULL, &cbRet); 527 if (RT_FAILURE(vrc)) 528 return errorArgument("Malformed hex string given to --set-opt-hex %u: %s\n", idAddOpt, ValueUnion.psz); 529 if (iPass == 1) 530 { 531 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 532 if (ptrConfig.isNull()) 533 return RTEXITCODE_FAILURE; 534 CHECK_ERROR2I_STMT(ptrConfig, SetOption((DhcpOpt_T)idAddOpt, DHCPOptionEncoding_Hex, 535 Bstr(ValueUnion.psz).raw()), rcExit = RTEXITCODE_FAILURE); 536 } 537 break; 538 } 539 540 case 'D': // --del-opt num 541 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 542 return errorSyntax("--del-opt does not apply to the 'add' subcommand"); 543 if (iPass == 1) 544 { 545 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 546 if (ptrConfig.isNull()) 547 return RTEXITCODE_FAILURE; 548 CHECK_ERROR2I_STMT(ptrConfig, RemoveOption((DhcpOpt_T)ValueUnion.u8), rcExit = RTEXITCODE_FAILURE); 549 } 550 break; 551 552 case DHCP_ADDMOD_ZAP_OPTIONS: 553 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 554 return errorSyntax("--zap-options does not apply to the 'add' subcommand"); 555 if (iPass == 1) 556 { 557 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 558 if (ptrConfig.isNull()) 559 return RTEXITCODE_FAILURE; 560 CHECK_ERROR2I_STMT(ptrConfig, RemoveAllOptions(), rcExit = RTEXITCODE_FAILURE); 561 } 562 break; 563 564 case 'q': // --min-lease-time 565 if (iPass == 1) 566 { 567 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 568 if (ptrConfig.isNull()) 569 return RTEXITCODE_FAILURE; 570 CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(MinLeaseTime)(ValueUnion.u32), rcExit = RTEXITCODE_FAILURE); 571 } 572 break; 573 574 case 'L': // --default-lease-time 575 if (iPass == 1) 576 { 577 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 578 if (ptrConfig.isNull()) 579 return RTEXITCODE_FAILURE; 580 CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(DefaultLeaseTime)(ValueUnion.u32), rcExit = RTEXITCODE_FAILURE); 581 } 582 break; 583 584 case 'Q': // --max-lease-time 585 if (iPass == 1) 586 { 587 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 588 if (ptrConfig.isNull()) 589 return RTEXITCODE_FAILURE; 590 CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(MaxLeaseTime)(ValueUnion.u32), rcExit = RTEXITCODE_FAILURE); 591 } 592 break; 593 594 case 'R': // --remove-config 595 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 596 return errorSyntax("--remove-config does not apply to the 'add' subcommand"); 597 if (Scope.getScope() == DHCPConfigScope_Global) 598 return errorSyntax("--remove-config cannot be applied to the global config"); 599 if (iPass == 1) 600 { 601 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 602 if (ptrConfig.isNull()) 603 return RTEXITCODE_FAILURE; 604 CHECK_ERROR2I_STMT(ptrConfig, Remove(), rcExit = RTEXITCODE_FAILURE); 605 } 606 Scope.setGlobal(); 607 break; 608 609 case 'f': // --fixed-address 610 if (Scope.getScope() != DHCPConfigScope_MachineNIC && Scope.getScope() != DHCPConfigScope_MAC) 611 return errorSyntax("--fixed-address can only be applied to a VM NIC or an MAC address"); 612 if (iPass == 1) 613 { 614 ComPtr<IDHCPIndividualConfig> &ptrIndividualConfig = Scope.getIndividual(ptrDHCPServer); 615 if (ptrIndividualConfig.isNull()) 616 return RTEXITCODE_FAILURE; 617 CHECK_ERROR2I_STMT(ptrIndividualConfig, COMSETTER(FixedAddress)(Bstr(ValueUnion.psz).raw()), 618 rcExit = RTEXITCODE_FAILURE); 619 } 620 break; 621 622 /* 623 * Group conditions: 624 */ 625 case DHCP_ADDMOD_INCL_MAC: 626 case DHCP_ADDMOD_EXCL_MAC: 627 case DHCP_ADDMOD_DEL_MAC: 628 case DHCP_ADDMOD_INCL_MAC_WILD: 629 case DHCP_ADDMOD_EXCL_MAC_WILD: 630 case DHCP_ADDMOD_DEL_MAC_WILD: 631 case DHCP_ADDMOD_INCL_VENDOR: 632 case DHCP_ADDMOD_EXCL_VENDOR: 633 case DHCP_ADDMOD_DEL_VENDOR: 634 case DHCP_ADDMOD_INCL_VENDOR_WILD: 635 case DHCP_ADDMOD_EXCL_VENDOR_WILD: 636 case DHCP_ADDMOD_DEL_VENDOR_WILD: 637 case DHCP_ADDMOD_INCL_USER: 638 case DHCP_ADDMOD_EXCL_USER: 639 case DHCP_ADDMOD_DEL_USER: 640 case DHCP_ADDMOD_INCL_USER_WILD: 641 case DHCP_ADDMOD_EXCL_USER_WILD: 642 case DHCP_ADDMOD_DEL_USER_WILD: 643 { 644 if (Scope.getScope() != DHCPConfigScope_Group) 645 return errorSyntax("A group must be selected to perform condition alterations."); 646 if (!*ValueUnion.psz) 647 return errorSyntax("Condition value cannot be empty"); /* or can it? */ 648 if (iPass != 1) 649 break; 650 651 DHCPGroupConditionType enmType; 652 switch (vrc) 653 { 654 case DHCP_ADDMOD_INCL_MAC: case DHCP_ADDMOD_EXCL_MAC: case DHCP_ADDMOD_DEL_MAC: 655 enmType = DHCPGroupConditionType_MAC; 656 break; 657 case DHCP_ADDMOD_INCL_MAC_WILD: case DHCP_ADDMOD_EXCL_MAC_WILD: case DHCP_ADDMOD_DEL_MAC_WILD: 658 enmType = DHCPGroupConditionType_MACWildcard; 659 break; 660 case DHCP_ADDMOD_INCL_VENDOR: case DHCP_ADDMOD_EXCL_VENDOR: case DHCP_ADDMOD_DEL_VENDOR: 661 enmType = DHCPGroupConditionType_vendorClassID; 662 break; 663 case DHCP_ADDMOD_INCL_VENDOR_WILD: case DHCP_ADDMOD_EXCL_VENDOR_WILD: case DHCP_ADDMOD_DEL_VENDOR_WILD: 664 enmType = DHCPGroupConditionType_vendorClassIDWildcard; 665 break; 666 case DHCP_ADDMOD_INCL_USER: case DHCP_ADDMOD_EXCL_USER: case DHCP_ADDMOD_DEL_USER: 667 enmType = DHCPGroupConditionType_userClassID; 668 break; 669 case DHCP_ADDMOD_INCL_USER_WILD: case DHCP_ADDMOD_EXCL_USER_WILD: case DHCP_ADDMOD_DEL_USER_WILD: 670 enmType = DHCPGroupConditionType_userClassIDWildcard; 671 break; 672 default: 673 AssertFailedReturn(RTEXITCODE_FAILURE); 674 } 675 676 int fInclusive; 677 switch (vrc) 678 { 679 case DHCP_ADDMOD_DEL_MAC: 680 case DHCP_ADDMOD_DEL_MAC_WILD: 681 case DHCP_ADDMOD_DEL_USER: 682 case DHCP_ADDMOD_DEL_USER_WILD: 683 case DHCP_ADDMOD_DEL_VENDOR: 684 case DHCP_ADDMOD_DEL_VENDOR_WILD: 685 fInclusive = -1; 686 break; 687 case DHCP_ADDMOD_EXCL_MAC: 688 case DHCP_ADDMOD_EXCL_MAC_WILD: 689 case DHCP_ADDMOD_EXCL_USER: 690 case DHCP_ADDMOD_EXCL_USER_WILD: 691 case DHCP_ADDMOD_EXCL_VENDOR: 692 case DHCP_ADDMOD_EXCL_VENDOR_WILD: 693 fInclusive = 0; 694 break; 695 case DHCP_ADDMOD_INCL_MAC: 696 case DHCP_ADDMOD_INCL_MAC_WILD: 697 case DHCP_ADDMOD_INCL_USER: 698 case DHCP_ADDMOD_INCL_USER_WILD: 699 case DHCP_ADDMOD_INCL_VENDOR: 700 case DHCP_ADDMOD_INCL_VENDOR_WILD: 701 fInclusive = 1; 702 break; 703 default: 704 AssertFailedReturn(RTEXITCODE_FAILURE); 705 } 706 707 ComPtr<IDHCPGroupConfig> &ptrGroupConfig = Scope.getGroup(ptrDHCPServer); 708 if (ptrGroupConfig.isNull()) 709 return RTEXITCODE_FAILURE; 710 if (fInclusive >= 0) 711 { 712 ComPtr<IDHCPGroupCondition> ptrCondition; 713 CHECK_ERROR2I_STMT(ptrGroupConfig, AddCondition((BOOL)fInclusive, enmType, Bstr(ValueUnion.psz).raw(), 714 ptrCondition.asOutParam()), rcExit = RTEXITCODE_FAILURE); 715 } 716 else 717 { 718 com::SafeIfaceArray<IDHCPGroupCondition> Conditions; 719 CHECK_ERROR2I_STMT(ptrGroupConfig, COMGETTER(Conditions)(ComSafeArrayAsOutParam(Conditions)), 720 rcExit = RTEXITCODE_FAILURE; break); 721 bool fFound = false; 722 for (size_t iCond = 0; iCond < Conditions.size(); iCond++) 723 { 724 DHCPGroupConditionType_T enmCurType = DHCPGroupConditionType_MAC; 725 CHECK_ERROR2I_STMT(Conditions[iCond], COMGETTER(Type)(&enmCurType), 726 rcExit = RTEXITCODE_FAILURE; continue); 727 if (enmCurType == enmType) 728 { 729 Bstr bstrValue; 730 CHECK_ERROR2I_STMT(Conditions[iCond], COMGETTER(Value)(bstrValue.asOutParam()), 731 rcExit = RTEXITCODE_FAILURE; continue); 732 if (RTUtf16CmpUtf8(bstrValue.raw(), ValueUnion.psz) == 0) 733 { 734 CHECK_ERROR2I_STMT(Conditions[iCond], Remove(), rcExit = RTEXITCODE_FAILURE); 735 fFound = true; 736 } 737 } 738 } 739 if (!fFound) 740 rcExit = RTMsgErrorExitFailure("Could not find any condition of type %d with value '%s' to delete", 741 enmType, ValueUnion.psz); 742 } 743 break; 744 } 745 746 case DHCP_ADDMOD_ZAP_CONDITIONS: 747 if (Scope.getScope() != DHCPConfigScope_Group) 748 return errorSyntax("--zap-conditions can only be with a group selected"); 749 if (iPass == 1) 750 { 751 ComPtr<IDHCPGroupConfig> &ptrGroupConfig = Scope.getGroup(ptrDHCPServer); 752 if (ptrGroupConfig.isNull()) 753 return RTEXITCODE_FAILURE; 754 CHECK_ERROR2I_STMT(ptrGroupConfig, RemoveAllConditions(), rcExit = RTEXITCODE_FAILURE); 755 } 756 break; 757 758 /* 759 * For backwards compatibility. Remove in 6.1 or later. 760 */ 761 762 case 'o': // --options - obsolete, ignored. 763 break; 764 765 case 'i': // --id 766 if (fNeedValueOrRemove) 767 return errorSyntax("Incomplete option sequence preseeding '--id=%u", ValueUnion.u8); 768 u8OptId = ValueUnion.u8; 769 fNeedValueOrRemove = true; 770 break; 771 772 case 'p': // --value 773 if (!fNeedValueOrRemove) 774 return errorSyntax("--value without --id=dhcp-opt-no"); 775 if (iPass == 1) 776 { 777 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 778 if (ptrConfig.isNull()) 779 return RTEXITCODE_FAILURE; 780 CHECK_ERROR2I_STMT(ptrConfig, SetOption((DhcpOpt_T)u8OptId, DHCPOptionEncoding_Legacy, 781 Bstr(ValueUnion.psz).raw()), rcExit = RTEXITCODE_FAILURE); 782 } 783 fNeedValueOrRemove = false; 784 break; 785 786 case 'r': // --remove 787 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 788 return errorSyntax("--remove does not apply to the 'add' subcommand"); 789 if (!fNeedValueOrRemove) 790 return errorSyntax("--remove without --id=dhcp-opt-no"); 791 792 if (iPass == 1) 793 { 794 ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer); 795 if (ptrConfig.isNull()) 796 return RTEXITCODE_FAILURE; 797 CHECK_ERROR2I_STMT(ptrConfig, RemoveOption((DhcpOpt_T)u8OptId), rcExit = RTEXITCODE_FAILURE); 798 } 799 fNeedValueOrRemove = false; 800 break; 801 802 default: 803 return errorGetOpt(vrc, &ValueUnion); 326 804 } 327 328 case 'D': // --del-opt num 329 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 330 return errorSyntax("--del-opt does not apply to the 'add' subcommand"); 331 pScopeOptions2Delete->push_back((DhcpOpt_T)ValueUnion.u8); 332 break; 333 334 /* 335 * For backwards compatibility. Remove in 6.1 or later. 336 */ 337 338 case 'o': // --options - obsolete, ignored. 339 break; 340 341 case 'i': // --id 342 if (fNeedValueOrRemove) 343 return errorSyntax("Incomplete option sequence preseeding '--id=%u", ValueUnion.u8); 344 u8OptId = ValueUnion.u8; 345 fNeedValueOrRemove = true; 346 break; 347 348 case 'p': // --value 349 if (!fNeedValueOrRemove) 350 return errorSyntax("--value without --id=dhcp-opt-no"); 351 pScopeOptions->push_back(DhcpOptSpec((DhcpOpt_T)u8OptId, Utf8Str(ValueUnion.psz))); 352 fNeedValueOrRemove = false; 353 break; 354 355 case 'r': // --remove 356 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 357 return errorSyntax("--remove does not apply to the 'add' subcommand"); 358 if (!fNeedValueOrRemove) 359 return errorSyntax("--remove without --id=dhcp-opt-no"); 360 pScopeOptions2Delete->push_back((DhcpOpt_T)u8OptId); 361 /** @todo remove from pScopeOptions */ 362 fNeedValueOrRemove = false; 363 break; 364 365 default: 366 return errorGetOpt(vrc, &ValueUnion); 367 } 368 } 369 370 /* 371 * Ensure we've got mandatory options and supply defaults 372 * where needed (modify case) 373 */ 374 if (!pCtx->pszNetwork && !pCtx->pszInterface) 375 return errorSyntax("You need to specify either --network or --interface to identify the DHCP server"); 376 377 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 378 { 805 } 806 807 if (iPass != 0) 808 break; 809 810 /* 811 * Ensure we've got mandatory options and supply defaults 812 * where needed (modify case) 813 */ 814 if (!pCtx->pszNetwork && !pCtx->pszInterface) 815 return errorSyntax("You need to specify either --network or --interface to identify the DHCP server"); 816 817 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 818 { 819 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 820 if (!pszServerIp) 821 rcExit = errorSyntax("Missing required option: --ip"); 822 if (!pszNetmask) 823 rcExit = errorSyntax("Missing required option: --netmask"); 824 if (!pszLowerIp) 825 rcExit = errorSyntax("Missing required option: --lowerip"); 826 if (!pszUpperIp) 827 rcExit = errorSyntax("Missing required option: --upperip"); 828 if (rcExit != RTEXITCODE_SUCCESS) 829 return rcExit; 830 } 831 832 /* 833 * Find or create the server. 834 */ 835 HRESULT rc; 836 Bstr NetName; 837 if (!pCtx->pszNetwork) 838 { 839 ComPtr<IHost> host; 840 CHECK_ERROR(pCtx->pArg->virtualBox, COMGETTER(Host)(host.asOutParam())); 841 842 ComPtr<IHostNetworkInterface> hif; 843 CHECK_ERROR(host, FindHostNetworkInterfaceByName(Bstr(pCtx->pszInterface).mutableRaw(), hif.asOutParam())); 844 if (FAILED(rc)) 845 return errorArgument("Could not find interface '%s'", pCtx->pszInterface); 846 847 CHECK_ERROR(hif, COMGETTER(NetworkName) (NetName.asOutParam())); 848 if (FAILED(rc)) 849 return errorArgument("Could not get network name for the interface '%s'", pCtx->pszInterface); 850 } 851 else 852 { 853 NetName = Bstr(pCtx->pszNetwork); 854 } 855 856 rc = pCtx->pArg->virtualBox->FindDHCPServerByNetworkName(NetName.mutableRaw(), ptrDHCPServer.asOutParam()); 857 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 858 { 859 if (SUCCEEDED(rc)) 860 return errorArgument("DHCP server already exists"); 861 862 CHECK_ERROR(pCtx->pArg->virtualBox, CreateDHCPServer(NetName.mutableRaw(), ptrDHCPServer.asOutParam())); 863 if (FAILED(rc)) 864 return errorArgument("Failed to create the DHCP server"); 865 } 866 else if (FAILED(rc)) 867 return errorArgument("DHCP server does not exist"); 868 869 /* 870 * Apply IDHCPServer settings: 871 */ 872 HRESULT hrc; 379 873 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 380 if (!pszServerIp) 381 rcExit = errorSyntax("Missing required option: --ip"); 382 if (!pszNetmask) 383 rcExit = errorSyntax("Missing required option: --netmask"); 384 if (!pszLowerIp) 385 rcExit = errorSyntax("Missing required option: --lowerip"); 386 if (!pszUpperIp) 387 rcExit = errorSyntax("Missing required option: --upperip"); 388 if (rcExit != RTEXITCODE_SUCCESS) 389 return rcExit; 390 } 391 392 /* 393 * Find or create the server. 394 */ 395 HRESULT rc; 396 Bstr NetName; 397 if (!pCtx->pszNetwork) 398 { 399 ComPtr<IHost> host; 400 CHECK_ERROR(pCtx->pArg->virtualBox, COMGETTER(Host)(host.asOutParam())); 401 402 ComPtr<IHostNetworkInterface> hif; 403 CHECK_ERROR(host, FindHostNetworkInterfaceByName(Bstr(pCtx->pszInterface).mutableRaw(), hif.asOutParam())); 404 if (FAILED(rc)) 405 return errorArgument("Could not find interface '%s'", pCtx->pszInterface); 406 407 CHECK_ERROR(hif, COMGETTER(NetworkName) (NetName.asOutParam())); 408 if (FAILED(rc)) 409 return errorArgument("Could not get network name for the interface '%s'", pCtx->pszInterface); 410 } 411 else 412 { 413 NetName = Bstr(pCtx->pszNetwork); 414 } 415 416 ComPtr<IDHCPServer> svr; 417 rc = pCtx->pArg->virtualBox->FindDHCPServerByNetworkName(NetName.mutableRaw(), svr.asOutParam()); 418 if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD) 419 { 420 if (SUCCEEDED(rc)) 421 return errorArgument("DHCP server already exists"); 422 423 CHECK_ERROR(pCtx->pArg->virtualBox, CreateDHCPServer(NetName.mutableRaw(), svr.asOutParam())); 424 if (FAILED(rc)) 425 return errorArgument("Failed to create the DHCP server"); 426 } 427 else if (FAILED(rc)) 428 return errorArgument("DHCP server does not exist"); 429 430 /* 431 * Apply settings. 432 */ 433 HRESULT hrc; 434 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 435 if (pszServerIp || pszNetmask || pszLowerIp || pszUpperIp) 436 { 437 Bstr bstrServerIp(pszServerIp); 438 Bstr bstrNetmask(pszNetmask); 439 Bstr bstrLowerIp(pszLowerIp); 440 Bstr bstrUpperIp(pszUpperIp); 441 442 if (!pszServerIp) 443 { 444 CHECK_ERROR2_RET(hrc, svr, COMGETTER(IPAddress)(bstrServerIp.asOutParam()), RTEXITCODE_FAILURE); 445 } 446 if (!pszNetmask) 447 { 448 CHECK_ERROR2_RET(hrc, svr, COMGETTER(NetworkMask)(bstrNetmask.asOutParam()), RTEXITCODE_FAILURE); 449 } 450 if (!pszLowerIp) 451 { 452 CHECK_ERROR2_RET(hrc, svr, COMGETTER(LowerIP)(bstrLowerIp.asOutParam()), RTEXITCODE_FAILURE); 453 } 454 if (!pszUpperIp) 455 { 456 CHECK_ERROR2_RET(hrc, svr, COMGETTER(UpperIP)(bstrUpperIp.asOutParam()), RTEXITCODE_FAILURE); 457 } 458 459 CHECK_ERROR2_STMT(hrc, svr, SetConfiguration(bstrServerIp.raw(), bstrNetmask.raw(), bstrLowerIp.raw(), bstrUpperIp.raw()), 460 rcExit = errorArgument("Failed to set configuration (%ls, %ls, %ls, %ls)", bstrServerIp.raw(), 461 bstrNetmask.raw(), bstrLowerIp.raw(), bstrUpperIp.raw())); 462 } 463 464 if (fEnabled >= 0) 465 { 466 CHECK_ERROR2_STMT(hrc, svr, COMSETTER(Enabled)((BOOL)fEnabled), rcExit = RTEXITCODE_FAILURE); 467 } 468 469 /* Remove options: */ 470 for (DhcpOptIdIterator itOptId = GlobalDhcpOptions2Delete.begin(); itOptId != GlobalDhcpOptions2Delete.end(); ++itOptId) 471 { 472 CHECK_ERROR2_STMT(hrc, svr, RemoveGlobalOption(*itOptId), rcExit = RTEXITCODE_FAILURE); 473 } 474 475 for (VmSlot2OptionIdsIterator itIdVector = VmSlot2Options2Delete.begin(); 476 itIdVector != VmSlot2Options2Delete.end(); ++itIdVector) 477 { 478 for (DhcpOptIdIterator itOptId = itIdVector->second.begin(); itOptId != itIdVector->second.end(); ++itOptId) 479 { 480 CHECK_ERROR2_STMT(hrc, svr, RemoveVmSlotOption(Bstr(itIdVector->first.VmName.c_str()).raw(), 481 itIdVector->first.u8Slot, *itOptId), 482 rcExit = RTEXITCODE_FAILURE); 483 } 484 } 485 486 /* Global Options */ 487 for (DhcpOptIterator itOpt = GlobalDhcpOptions.begin(); itOpt != GlobalDhcpOptions.end(); ++itOpt) 488 { 489 CHECK_ERROR2_STMT(hrc, svr, AddGlobalOption(itOpt->first, com::Bstr(itOpt->second.c_str()).raw()), 490 rcExit = RTEXITCODE_FAILURE); 491 } 492 493 /* VM slot options. */ 494 for (VmSlot2OptionsIterator it = VmSlot2Options.begin(); it != VmSlot2Options.end(); ++it) 495 { 496 for (DhcpOptIterator itOpt = it->second.begin(); itOpt != it->second.end(); ++itOpt) 497 { 498 CHECK_ERROR2_STMT(hrc, svr, AddVmSlotOption(Bstr(it->first.VmName.c_str()).raw(), it->first.u8Slot, itOpt->first, 499 com::Bstr(itOpt->second).raw()), 500 rcExit = RTEXITCODE_FAILURE); 874 if (pszServerIp || pszNetmask || pszLowerIp || pszUpperIp) 875 { 876 Bstr bstrServerIp(pszServerIp); 877 Bstr bstrNetmask(pszNetmask); 878 Bstr bstrLowerIp(pszLowerIp); 879 Bstr bstrUpperIp(pszUpperIp); 880 881 if (!pszServerIp) 882 { 883 CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(IPAddress)(bstrServerIp.asOutParam()), RTEXITCODE_FAILURE); 884 } 885 if (!pszNetmask) 886 { 887 CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(NetworkMask)(bstrNetmask.asOutParam()), RTEXITCODE_FAILURE); 888 } 889 if (!pszLowerIp) 890 { 891 CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(LowerIP)(bstrLowerIp.asOutParam()), RTEXITCODE_FAILURE); 892 } 893 if (!pszUpperIp) 894 { 895 CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(UpperIP)(bstrUpperIp.asOutParam()), RTEXITCODE_FAILURE); 896 } 897 898 CHECK_ERROR2_STMT(hrc, ptrDHCPServer, SetConfiguration(bstrServerIp.raw(), bstrNetmask.raw(), 899 bstrLowerIp.raw(), bstrUpperIp.raw()), 900 rcExit = errorArgument("Failed to set configuration (%ls, %ls, %ls, %ls)", bstrServerIp.raw(), 901 bstrNetmask.raw(), bstrLowerIp.raw(), bstrUpperIp.raw())); 902 } 903 904 if (fEnabled >= 0) 905 { 906 CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMSETTER(Enabled)((BOOL)fEnabled), rcExit = RTEXITCODE_FAILURE); 501 907 } 502 908 } -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp
r79748 r79771 859 859 { 860 860 HRESULT hrcRet = S_OK; 861 com::SafeIfaceArray<IDHCPServer> svrs;862 CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(DHCPServers)(ComSafeArrayAsOutParam( svrs)), hrcCheck);863 for (size_t i = 0; i < svrs.size(); ++i)861 com::SafeIfaceArray<IDHCPServer> DHCPServers; 862 CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(DHCPServers)(ComSafeArrayAsOutParam(DHCPServers)), hrcCheck); 863 for (size_t i = 0; i < DHCPServers.size(); ++i) 864 864 { 865 865 if (i > 0) 866 866 RTPrintf("\n"); 867 867 868 ComPtr<IDHCPServer> svr = svrs[i];868 ComPtr<IDHCPServer> ptrDHCPServer = DHCPServers[i]; 869 869 Bstr bstr; 870 CHECK_ERROR2I_STMT( svr, COMGETTER(NetworkName)(bstr.asOutParam()), hrcRet = hrcCheck);870 CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(NetworkName)(bstr.asOutParam()), hrcRet = hrcCheck); 871 871 RTPrintf("NetworkName: %ls\n", bstr.raw()); 872 872 873 CHECK_ERROR2I_STMT( svr, COMGETTER(IPAddress)(bstr.asOutParam()), hrcRet = hrcCheck);873 CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(IPAddress)(bstr.asOutParam()), hrcRet = hrcCheck); 874 874 RTPrintf("Dhcpd IP: %ls\n", bstr.raw()); 875 875 876 CHECK_ERROR2I_STMT( svr, COMGETTER(LowerIP)(bstr.asOutParam()), hrcRet = hrcCheck);876 CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(LowerIP)(bstr.asOutParam()), hrcRet = hrcCheck); 877 877 RTPrintf("LowerIPAddress: %ls\n", bstr.raw()); 878 878 879 CHECK_ERROR2I_STMT( svr, COMGETTER(UpperIP)(bstr.asOutParam()), hrcRet = hrcCheck);879 CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(UpperIP)(bstr.asOutParam()), hrcRet = hrcCheck); 880 880 RTPrintf("UpperIPAddress: %ls\n", bstr.raw()); 881 881 882 CHECK_ERROR2I_STMT( svr, COMGETTER(NetworkMask)(bstr.asOutParam()), hrcRet = hrcCheck);882 CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(NetworkMask)(bstr.asOutParam()), hrcRet = hrcCheck); 883 883 RTPrintf("NetworkMask: %ls\n", bstr.raw()); 884 884 885 885 BOOL fEnabled = FALSE; 886 CHECK_ERROR2I_STMT( svr, COMGETTER(Enabled)(&fEnabled), hrcRet = hrcCheck);886 CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(Enabled)(&fEnabled), hrcRet = hrcCheck); 887 887 RTPrintf("Enabled: %s\n", fEnabled ? "Yes" : "No"); 888 888 … … 891 891 HRESULT hrc; 892 892 ComPtr<IDHCPGlobalConfig> ptrGlobal; 893 CHECK_ERROR2_STMT(hrc, svr, COMGETTER(GlobalConfig)(ptrGlobal.asOutParam()), hrcRet = hrc);893 CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMGETTER(GlobalConfig)(ptrGlobal.asOutParam()), hrcRet = hrc); 894 894 if (SUCCEEDED(hrc)) 895 895 { … … 901 901 /* Group configurations: */ 902 902 com::SafeIfaceArray<IDHCPGroupConfig> Groups; 903 CHECK_ERROR2_STMT(hrc, svr, COMGETTER(GroupConfigs)(ComSafeArrayAsOutParam(Groups)), hrcRet = hrc);903 CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMGETTER(GroupConfigs)(ComSafeArrayAsOutParam(Groups)), hrcRet = hrc); 904 904 if (FAILED(hrc)) 905 905 RTPrintf("Groups: %Rrc\n", hrc); … … 913 913 RTPrintf("Group: %ls\n", bstr.raw()); 914 914 915 com::SafeIfaceArray<IDHCPGroupCondition> Conditions; 916 CHECK_ERROR2_STMT(hrc, Groups[iGrp], COMGETTER(Conditions)(ComSafeArrayAsOutParam(Conditions)), hrcRet = hrc); 917 if (FAILED(hrc)) 918 RTPrintf(" Conditions: %Rhrc\n", hrc); 919 else if (Conditions.size() == 0) 920 RTPrintf(" Conditions: None\n"); 921 else 922 for (size_t iCond = 0; iCond < Conditions.size(); iCond++) 923 { 924 BOOL fInclusive = TRUE; 925 CHECK_ERROR2_STMT(hrc, Conditions[iCond], COMGETTER(Inclusive)(&fInclusive), hrcRet = hrc); 926 DHCPGroupConditionType_T enmType = DHCPGroupConditionType_MAC; 927 CHECK_ERROR2_STMT(hrc, Conditions[iCond], COMGETTER(Type)(&enmType), hrcRet = hrc); 928 CHECK_ERROR2_STMT(hrc, Conditions[iCond], COMGETTER(Value)(bstr.asOutParam()), hrcRet = hrc); 929 930 RTPrintf(" Conditions: %s %s %ls\n", 931 fInclusive ? "include" : "exclude", 932 enmType == DHCPGroupConditionType_MAC ? "MAC " 933 : enmType == DHCPGroupConditionType_MACWildcard ? "MAC* " 934 : enmType == DHCPGroupConditionType_vendorClassID ? "VendorCID " 935 : enmType == DHCPGroupConditionType_vendorClassIDWildcard ? "VendorCID*" 936 : enmType == DHCPGroupConditionType_userClassID ? "UserCID " 937 : enmType == DHCPGroupConditionType_userClassIDWildcard ? "UserCID* " 938 : "!UNKNOWN! ", 939 bstr.raw()); 940 } 941 915 942 hrc = showDhcpConfig(Groups[iGrp]); 916 943 if (FAILED(hrc)) … … 922 949 /* Individual host / NIC configurations: */ 923 950 com::SafeIfaceArray<IDHCPIndividualConfig> Hosts; 924 CHECK_ERROR2_STMT(hrc, svr, COMGETTER(IndividualConfigs)(ComSafeArrayAsOutParam(Hosts)), hrcRet = hrc);951 CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMGETTER(IndividualConfigs)(ComSafeArrayAsOutParam(Hosts)), hrcRet = hrc); 925 952 if (FAILED(hrc)) 926 953 RTPrintf("Individual Configs: %Rrc\n", hrc); … … 936 963 if (enmScope == DHCPConfigScope_MAC) 937 964 { 938 CHECK_ERROR2I_STMT(Hosts[i ], COMGETTER(MACAddress)(bstr.asOutParam()), hrcRet = hrcCheck);965 CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(MACAddress)(bstr.asOutParam()), hrcRet = hrcCheck); 939 966 RTPrintf("Individual Config: MAC %ls\n", bstr.raw()); 940 967 } … … 942 969 { 943 970 ULONG uSlot = 0; 944 CHECK_ERROR2I_STMT(Hosts[i ], COMGETTER(Slot)(&uSlot), hrcRet = hrcCheck);945 CHECK_ERROR2I_STMT(Hosts[i ], COMGETTER(MachineId)(bstr.asOutParam()), hrcRet = hrcCheck);971 CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(Slot)(&uSlot), hrcRet = hrcCheck); 972 CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(MachineId)(bstr.asOutParam()), hrcRet = hrcCheck); 946 973 Bstr bstrMACAddress; 947 hrc = Hosts[i ]->COMGETTER(MACAddress)(bstrMACAddress.asOutParam()); /* No CHECK_ERROR2 stuff! */974 hrc = Hosts[iHost]->COMGETTER(MACAddress)(bstrMACAddress.asOutParam()); /* No CHECK_ERROR2 stuff! */ 948 975 if (SUCCEEDED(hrc)) 949 976 RTPrintf("Individual Config: VM NIC: %ls slot %u, MAC %ls\n", bstr.raw(), uSlot, bstrMACAddress.raw()); … … 952 979 } 953 980 954 CHECK_ERROR2I_STMT(Hosts[i ], COMGETTER(FixedAddress)(bstr.asOutParam()), hrcRet = hrcCheck);981 CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(FixedAddress)(bstr.asOutParam()), hrcRet = hrcCheck); 955 982 if (bstr.isNotEmpty()) 956 983 RTPrintf(" Fixed Address: %ls\n", bstr.raw()); … … 958 985 RTPrintf(" Fixed Address: dynamic\n"); 959 986 960 hrc = showDhcpConfig(Hosts[i ]);987 hrc = showDhcpConfig(Hosts[iHost]); 961 988 if (FAILED(hrc)) 962 989 hrcRet = hrc; -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r79747 r79771 2140 2140 <interface 2141 2141 name="IDHCPConfig" extends="$unknown" 2142 uuid="3 8fdb664-f65e-4905-ee56-a8a912871bbf"2142 uuid="39cdde66-cfc3-4eec-7427-faf5b16469ae" 2143 2143 wsmap="managed" 2144 2144 reservedMethods="8" reservedAttributes="16" … … 2223 2223 </param> 2224 2224 </method> 2225 2226 <method name="remove"> 2227 <desc> 2228 Remove this group or individual configuration. 2229 Will of course not work on global configurations. 2230 </desc> 2231 </method> 2232 2225 2233 </interface> 2226 2234 … … 2260 2268 <interface 2261 2269 name="IDHCPGroupConfig" extends="IDHCPConfig" 2262 uuid=" 406a5eca-d032-4f65-a882-6bb626a424a5"2270 uuid="537707f7-ebf9-4d5c-7aea-877bfc4256ba" 2263 2271 wsmap="managed" 2264 2272 reservedMethods="8" reservedAttributes="8" … … 2282 2290 2283 2291 <method name="addCondition"> 2292 <desc>Adds a new condition.</desc> 2284 2293 <param name="inclusive" dir="in" type="boolean"/> 2285 2294 <param name="type" dir="in" type="DHCPGroupConditionType"/> 2286 2295 <param name="value" dir="in" type="wstring"/> 2287 2296 <param name="condition" dir="return" type="IDHCPGroupCondition"/> 2297 </method> 2298 2299 <method name="removeAllConditions"> 2300 <desc>Removes all conditions.</desc> 2288 2301 </method> 2289 2302 -
trunk/src/VBox/Main/include/DHCPConfigImpl.h
r79747 r79771 99 99 HRESULT i_getAllOptions(std::vector<DhcpOpt_T> &aOptions, std::vector<DHCPOptionEncoding_T> &aEncodings, 100 100 std::vector<com::Utf8Str> &aValues); 101 virtual HRESULT i_remove(); 101 102 /** @} */ 102 103 … … 178 179 return i_getAllOptions(aOptions, aEncodings, aValues); 179 180 } 181 182 HRESULT remove() RT_OVERRIDE 183 { 184 return i_remove(); 185 } 180 186 /** @} */ 181 187 … … 184 190 HRESULT i_removeOption(DhcpOpt_T aOption) RT_OVERRIDE; 185 191 HRESULT i_removeAllOptions() RT_OVERRIDE; 192 HRESULT i_remove() RT_OVERRIDE; 186 193 }; 187 194 … … 225 232 226 233 HRESULT i_saveSettings(settings::DHCPGroupCondition &a_rDst); 234 static HRESULT i_validateTypeAndValue(DHCPGroupConditionType_T enmType, com::Utf8Str const &strValue, 235 VirtualBoxBase *pErrorDst); 227 236 228 237 protected: … … 326 335 return i_getAllOptions(aOptions, aEncodings, aValues); 327 336 } 337 338 HRESULT remove() RT_OVERRIDE 339 { 340 return i_remove(); 341 } 328 342 /** @} */ 329 343 … … 332 346 HRESULT addCondition(BOOL aInclusive, DHCPGroupConditionType_T aType, const com::Utf8Str &aValue, 333 347 ComPtr<IDHCPGroupCondition> &aCondition) RT_OVERRIDE; 348 HRESULT removeAllConditions() RT_OVERRIDE; 334 349 /** @} */ 335 350 }; … … 444 459 return i_getAllOptions(aOptions, aEncodings, aValues); 445 460 } 461 462 HRESULT remove() RT_OVERRIDE 463 { 464 return i_remove(); 465 } 446 466 /** @} */ 447 467 -
trunk/src/VBox/Main/include/DHCPServerImpl.h
r79761 r79771 69 69 * @{ */ 70 70 HRESULT i_saveSettings(settings::DHCPServer &data); 71 HRESULT i_removeConfig(DHCPConfig *pConfig, DHCPConfigScope_T enmScope); 71 72 /** @} */ 72 73 -
trunk/src/VBox/Main/src-server/DHCPConfigImpl.cpp
r79761 r79771 24 24 #include "LoggingNew.h" 25 25 26 #include <iprt/ctype.h> 26 27 #include <iprt/errcore.h> 27 28 #include <iprt/net.h> … … 33 34 34 35 #include "AutoCaller.h" 36 #include "DHCPServerImpl.h" 35 37 #include "MachineImpl.h" 36 38 #include "VirtualBoxImpl.h" … … 271 273 272 274 275 HRESULT DHCPConfig::i_remove() 276 { 277 return m_pParent->i_removeConfig(this, m_enmScope); 278 } 279 280 281 273 282 /** 274 283 * Causes the global VirtualBox configuration file to be written … … 450 459 451 460 461 /** 462 * Overriden to prevent removal. 463 */ 464 HRESULT DHCPGlobalConfig::i_remove() 465 { 466 return setError(E_ACCESSDENIED, tr("Cannot delete the global config")); 467 } 468 469 452 470 453 471 /********************************************************************************************************************************* … … 500 518 501 519 520 /** 521 * Worker for validating the condition value according to the given type. 522 * 523 * @returns COM status code. 524 * @param enmType The condition type. 525 * @param strValue The condition value. 526 * @param pErrorDst The object to use for reporting errors. 527 */ 528 /*static*/ HRESULT DHCPGroupCondition::i_validateTypeAndValue(DHCPGroupConditionType_T enmType, com::Utf8Str const &strValue, 529 VirtualBoxBase *pErrorDst) 530 { 531 switch (enmType) 532 { 533 case DHCPGroupConditionType_MAC: 534 { 535 RTMAC MACAddress; 536 int vrc = RTNetStrToMacAddr(strValue.c_str(), &MACAddress); 537 if (RT_SUCCESS(vrc)) 538 return S_OK; 539 return pErrorDst->setError(E_INVALIDARG, pErrorDst->tr("Not a valid MAC address: %s"), strValue.c_str()); 540 } 541 542 case DHCPGroupConditionType_MACWildcard: 543 { 544 /* This must be colon separated double xdigit bytes. Single bytes 545 shorthand or raw hexstrings won't match anything. For reasons of 546 simplicity, '?' can only be used to match xdigits, '*' must match 1+ 547 chars. */ 548 /** @todo test this properly... */ 549 const char *psz = strValue.c_str(); 550 size_t off = 0; 551 unsigned cPairsLeft = 6; 552 bool fSeenAsterisk = false; 553 for (;;) 554 { 555 char ch = psz[off++]; 556 if (RT_C_IS_XDIGIT(ch) || ch == '?') 557 { 558 ch = psz[off++]; 559 if (RT_C_IS_XDIGIT(ch) || ch == '?') 560 { 561 ch = psz[off++]; 562 cPairsLeft -= 1; 563 if (cPairsLeft == 0) 564 { 565 if (!ch) 566 return S_OK; 567 return pErrorDst->setError(E_INVALIDARG, 568 pErrorDst->tr("Trailing chars in MAC wildcard address: %s (offset %zu)"), 569 psz, off - 1); 570 } 571 if (ch == ':' || ch == '*') 572 continue; 573 if (ch == '\0' && fSeenAsterisk) 574 return S_OK; 575 return pErrorDst->setError(E_INVALIDARG, 576 pErrorDst->tr("Malformed MAC wildcard address: %s (offset %zu)"), 577 psz, off - 1); 578 } 579 580 if (ch == '*') 581 { 582 fSeenAsterisk = true; 583 do 584 ch = psz[off++]; 585 while (ch == '*'); 586 if (ch == '\0') 587 return S_OK; 588 cPairsLeft -= 1; 589 if (cPairsLeft == 0) 590 return pErrorDst->setError(E_INVALIDARG, 591 pErrorDst->tr("Trailing chars in MAC wildcard address: %s (offset %zu)"), 592 psz, off - 1); 593 if (ch == ':') 594 continue; 595 } 596 else 597 return pErrorDst->setError(E_INVALIDARG, pErrorDst->tr("Malformed MAC wildcard address: %s (offset %zu)"), 598 psz, off - 1); 599 } 600 else if (ch == '*') 601 { 602 fSeenAsterisk = true; 603 do 604 ch = psz[off++]; 605 while (ch == '*'); 606 if (ch == '\0') 607 return S_OK; 608 if (ch == ':') 609 { 610 cPairsLeft -= 1; 611 if (cPairsLeft == 0) 612 return pErrorDst->setError(E_INVALIDARG, 613 pErrorDst->tr("Trailing chars in MAC wildcard address: %s (offset %zu)"), 614 psz, off - 1); 615 continue; 616 } 617 618 } 619 else 620 return pErrorDst->setError(E_INVALIDARG, pErrorDst->tr("Malformed MAC wildcard address: %s (offset %zu)"), 621 psz, off - 1); 622 623 /* Pick up after '*' in the two cases above: ch is not ':' or '\0'. */ 624 Assert(ch != ':' && ch != '\0'); 625 if (RT_C_IS_XDIGIT(ch) || ch == '?') 626 { 627 ch = psz[off++]; 628 if (RT_C_IS_XDIGIT(ch) || ch == '?' || ch == '*') 629 { 630 off -= 2; 631 continue; 632 } 633 if (ch == ':') 634 { 635 ch = psz[off++]; 636 if (ch == '\0') 637 return S_OK; 638 cPairsLeft -= 1; 639 if (cPairsLeft == 0) 640 return pErrorDst->setError(E_INVALIDARG, 641 pErrorDst->tr("Trailing chars in MAC wildcard address: %s (offset %zu)"), 642 psz, off - 1); 643 continue; 644 } 645 if (ch == '\0') 646 return S_OK; 647 return pErrorDst->setError(E_INVALIDARG, 648 pErrorDst->tr("Trailing chars in MAC wildcard address: %s (offset %zu)"), 649 psz, off - 1); 650 } 651 return pErrorDst->setError(E_INVALIDARG, 652 pErrorDst->tr("Malformed MAC wildcard address: %s (offset %zu)"), 653 psz, off - 1); 654 } 655 break; 656 } 657 658 case DHCPGroupConditionType_vendorClassID: 659 case DHCPGroupConditionType_vendorClassIDWildcard: 660 case DHCPGroupConditionType_userClassID: 661 case DHCPGroupConditionType_userClassIDWildcard: 662 if (strValue.length() == 0) 663 return pErrorDst->setError(E_INVALIDARG, pErrorDst->tr("Value cannot be empty")); 664 if (strValue.length() < 255) 665 return pErrorDst->setError(E_INVALIDARG, pErrorDst->tr("Value is too long: %zu bytes"), strValue.length()); 666 break; 667 668 default: 669 return pErrorDst->setError(E_INVALIDARG, pErrorDst->tr("Invalid condition type: %d"), enmType); 670 } 671 672 return S_OK; 673 } 674 675 502 676 HRESULT DHCPGroupCondition::getInclusive(BOOL *aInclusive) 503 677 { … … 534 708 if (aType == m_enmType) 535 709 return S_OK; 710 HRESULT hrc = i_validateTypeAndValue(aType, m_strValue, this); 711 if (FAILED(hrc)) 712 return hrc; 536 713 m_enmType = aType; 537 714 } … … 553 730 if (aValue == m_strValue) 554 731 return S_OK; 555 HRESULT hrc = m_strValue.assignEx(aValue); 732 HRESULT hrc = i_validateTypeAndValue(m_enmType, aValue, this); 733 if (FAILED(hrc)) 734 return hrc; 735 hrc = m_strValue.assignEx(aValue); 556 736 if (FAILED(hrc)) 557 737 return hrc; … … 728 908 ComPtr<IDHCPGroupCondition> &aCondition) 729 909 { 730 ComObjPtr<DHCPGroupCondition> ptrCondition; 731 HRESULT hrc = ptrCondition.createObject(); 732 if (SUCCEEDED(hrc)) 733 hrc = ptrCondition->initWithDefaults(this, aInclusive != FALSE, aType, aValue); 734 if (SUCCEEDED(hrc)) 735 { 736 hrc = ptrCondition.queryInterfaceTo(aCondition.asOutParam()); 910 /* 911 * Valdiate it. 912 */ 913 HRESULT hrc = DHCPGroupCondition::i_validateTypeAndValue(aType, aValue, this); 914 if (SUCCEEDED(hrc)) 915 { 916 /* 917 * Add it. 918 */ 919 ComObjPtr<DHCPGroupCondition> ptrCondition; 920 hrc = ptrCondition.createObject(); 921 if (SUCCEEDED(hrc)) 922 hrc = ptrCondition->initWithDefaults(this, aInclusive != FALSE, aType, aValue); 737 923 if (SUCCEEDED(hrc)) 738 924 { 739 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);740 try925 hrc = ptrCondition.queryInterfaceTo(aCondition.asOutParam()); 926 if (SUCCEEDED(hrc)) 741 927 { 742 m_Conditions.push_back(ptrCondition); 743 } 744 catch (std::bad_alloc &) 745 { 746 aCondition.setNull(); 747 return E_OUTOFMEMORY; 928 { 929 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 930 try 931 { 932 m_Conditions.push_back(ptrCondition); 933 } 934 catch (std::bad_alloc &) 935 { 936 aCondition.setNull(); 937 return E_OUTOFMEMORY; 938 } 939 } 940 941 hrc = i_doWriteConfig(); 942 if (FAILED(hrc)) 943 aCondition.setNull(); 748 944 } 749 945 } … … 751 947 752 948 return hrc; 949 } 950 951 952 HRESULT DHCPGroupConfig::removeAllConditions() 953 { 954 { 955 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 956 if (m_Conditions.size() == 0) 957 return S_OK; 958 959 /** @todo sever the weak parent link for each entry... */ 960 m_Conditions.erase(m_Conditions.begin(), m_Conditions.end()); 961 } 962 963 return i_doWriteConfig(); 753 964 } 754 965 -
trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp
r79761 r79771 311 311 312 312 313 /** 314 * Called by VirtualBox to save our settings. 315 */ 313 316 HRESULT DHCPServer::i_saveSettings(settings::DHCPServer &rData) 314 317 { … … 367 370 368 371 return hrc; 372 } 373 374 375 HRESULT DHCPServer::i_removeConfig(DHCPConfig *pConfig, DHCPConfigScope_T enmScope) 376 { 377 { 378 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 379 380 bool fFound = false; 381 switch (enmScope) 382 { 383 case DHCPConfigScope_Group: 384 for (Data::GroupConfigIterator it = m->groupConfigs.begin(); it != m->groupConfigs.end();) 385 { 386 DHCPConfig *pCurConfig = it->second; 387 if (pCurConfig == pConfig) 388 { 389 fFound = true; 390 it = m->groupConfigs.erase(it); 391 } 392 else 393 ++it; 394 } 395 break; 396 397 case DHCPConfigScope_MAC: 398 case DHCPConfigScope_MachineNIC: 399 for (Data::IndividualConfigIterator it = m->individualConfigs.begin(); it != m->individualConfigs.end();) 400 { 401 DHCPConfig *pCurConfig = it->second; 402 if (pCurConfig == pConfig) 403 { 404 fFound = true; 405 it = m->individualConfigs.erase(it); 406 } 407 else 408 ++it; 409 } 410 break; 411 412 default: 413 AssertFailedReturn(E_FAIL); 414 } 415 416 /* Don't complain if already removed, right? */ 417 if (!fFound) 418 return S_OK; 419 } 420 421 return i_doSaveSettings(); 369 422 } 370 423
Note:
See TracChangeset
for help on using the changeset viewer.