VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 5 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
RevLine 
[17488]1/* $Id: VBoxManageHostonly.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of hostonlyif command.
4 */
5
6/*
[76553]7 * Copyright (C) 2006-2019 Oracle Corporation
[17488]8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
[57358]18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
[17488]22#ifndef VBOX_ONLY_DOCS
23#include <VBox/com/com.h>
24#include <VBox/com/array.h>
25#include <VBox/com/ErrorInfo.h>
[20928]26#include <VBox/com/errorprint.h>
[17488]27#include <VBox/com/VirtualBox.h>
28#endif /* !VBOX_ONLY_DOCS */
29
30#include <iprt/cidr.h>
31#include <iprt/param.h>
32#include <iprt/path.h>
33#include <iprt/stream.h>
34#include <iprt/string.h>
35#include <iprt/net.h>
36#include <iprt/getopt.h>
[18108]37#include <iprt/ctype.h>
[17488]38
39#include <VBox/log.h>
40
41#include "VBoxManage.h"
42
43#ifndef VBOX_ONLY_DOCS
44using namespace com;
45
[65827]46static const RTGETOPTDEF g_aHostOnlyCreateOptions[] =
47{
48 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
49};
50
[35317]51#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
[56118]52static RTEXITCODE handleCreate(HandlerArg *a)
[17488]53{
[56118]54 /*
55 * Parse input.
56 */
[65827]57 bool fMachineReadable = false;
[56118]58 RTGETOPTUNION ValueUnion;
59 RTGETOPTSTATE GetState;
[65827]60 RTGetOptInit(&GetState, a->argc, a->argv, g_aHostOnlyCreateOptions,
61 RT_ELEMENTS(g_aHostOnlyCreateOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
62 int c;
63 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
64 {
65 switch (c)
66 {
67 case 'M': // --machinereadable
68 fMachineReadable = true;
69 break;
[17488]70
[65827]71 default:
72 return errorGetOpt(USAGE_HOSTONLYIFS, c, &ValueUnion);
73 }
74 }
75
[56118]76 /*
77 * Do the work.
78 */
[17488]79 ComPtr<IHost> host;
[56118]80 CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
[17488]81
82 ComPtr<IHostNetworkInterface> hif;
83 ComPtr<IProgress> progress;
84
[56118]85 CHECK_ERROR2I_RET(host, CreateHostOnlyNetworkInterface(hif.asOutParam(), progress.asOutParam()), RTEXITCODE_FAILURE);
[17488]86
[65827]87 if (fMachineReadable)
88 {
89 CHECK_PROGRESS_ERROR_RET(progress, (""), RTEXITCODE_FAILURE);
90 }
91 else
92 {
93 /*HRESULT hrc =*/ showProgress(progress);
94 CHECK_PROGRESS_ERROR_RET(progress, ("Failed to create the host-only adapter"), RTEXITCODE_FAILURE);
95 }
[17488]96
[56118]97 Bstr bstrName;
98 CHECK_ERROR2I(hif, COMGETTER(Name)(bstrName.asOutParam()));
[17679]99
[65827]100 if (fMachineReadable)
101 RTPrintf("%ls", bstrName.raw());
102 else
103 RTPrintf("Interface '%ls' was successfully created\n", bstrName.raw());
[56118]104 return RTEXITCODE_SUCCESS;
[17488]105}
106
[56118]107static RTEXITCODE handleRemove(HandlerArg *a)
[17488]108{
[56118]109 /*
110 * Parse input.
111 */
112 const char *pszName = NULL;
113 int ch;
114 RTGETOPTUNION ValueUnion;
115 RTGETOPTSTATE GetState;
116 RTGetOptInit(&GetState, a->argc, a->argv, NULL, 0, 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
117 while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
118 switch (ch)
119 {
120 case VINF_GETOPT_NOT_OPTION:
121 if (pszName)
122 return errorSyntax(USAGE_HOSTONLYIFS, "Only one interface name can be specified");
123 pszName = ValueUnion.psz;
124 break;
[17488]125
[56118]126 default:
127 return errorGetOpt(USAGE_HOSTONLYIFS, ch, &ValueUnion);
128 }
129 if (!pszName)
130 return errorSyntax(USAGE_HOSTONLYIFS, "No interface name was specified");
[17488]131
[56118]132 /*
133 * Do the work.
134 */
[17488]135 ComPtr<IHost> host;
[56118]136 CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
[17488]137
138 ComPtr<IHostNetworkInterface> hif;
[56118]139 CHECK_ERROR2I_RET(host, FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam()), RTEXITCODE_FAILURE);
[17488]140
[19239]141 Bstr guid;
[56118]142 CHECK_ERROR2I_RET(hif, COMGETTER(Id)(guid.asOutParam()), RTEXITCODE_FAILURE);
[17488]143
144 ComPtr<IProgress> progress;
[56118]145 CHECK_ERROR2I_RET(host, RemoveHostOnlyNetworkInterface(guid.raw(), progress.asOutParam()), RTEXITCODE_FAILURE);
[17488]146
[63300]147 /*HRESULT hrc =*/ showProgress(progress);
[56118]148 CHECK_PROGRESS_ERROR_RET(progress, ("Failed to remove the host-only adapter"), RTEXITCODE_FAILURE);
[17488]149
[56118]150 return RTEXITCODE_SUCCESS;
[17488]151}
152#endif
153
[18108]154static const RTGETOPTDEF g_aHostOnlyIPOptions[]
[17488]155 = {
[18108]156 { "--dhcp", 'd', RTGETOPT_REQ_NOTHING },
157 { "-dhcp", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
158 { "--ip", 'a', RTGETOPT_REQ_STRING },
159 { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated
160 { "--netmask", 'm', RTGETOPT_REQ_STRING },
161 { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated
162 { "--ipv6", 'b', RTGETOPT_REQ_STRING },
163 { "-ipv6", 'b', RTGETOPT_REQ_STRING }, // deprecated
164 { "--netmasklengthv6", 'l', RTGETOPT_REQ_UINT8 },
165 { "-netmasklengthv6", 'l', RTGETOPT_REQ_UINT8 } // deprecated
[17488]166 };
167
[56118]168static RTEXITCODE handleIpConfig(HandlerArg *a)
[17488]169{
[56118]170 bool fDhcp = false;
171 bool fNetmasklengthv6 = false;
172 uint32_t uNetmasklengthv6 = UINT32_MAX;
173 const char *pszIpv6 = NULL;
174 const char *pszIp = NULL;
175 const char *pszNetmask = NULL;
176 const char *pszName = NULL;
[17488]177
178 int c;
179 RTGETOPTUNION ValueUnion;
180 RTGETOPTSTATE GetState;
[56118]181 RTGetOptInit(&GetState, a->argc, a->argv, g_aHostOnlyIPOptions, RT_ELEMENTS(g_aHostOnlyIPOptions),
182 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
183 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
[17488]184 {
185 switch (c)
186 {
[18108]187 case 'd': // --dhcp
[56118]188 fDhcp = true;
189 break;
[18108]190 case 'a': // --ip
[56118]191 if (pszIp)
192 RTMsgWarning("The --ip option is specified more than once");
193 pszIp = ValueUnion.psz;
194 break;
[18108]195 case 'm': // --netmask
[56118]196 if (pszNetmask)
197 RTMsgWarning("The --netmask option is specified more than once");
198 pszNetmask = ValueUnion.psz;
199 break;
[18108]200 case 'b': // --ipv6
[56118]201 if (pszIpv6)
202 RTMsgWarning("The --ipv6 option is specified more than once");
203 pszIpv6 = ValueUnion.psz;
204 break;
[18108]205 case 'l': // --netmasklengthv6
[56118]206 if (fNetmasklengthv6)
207 RTMsgWarning("The --netmasklengthv6 option is specified more than once");
208 fNetmasklengthv6 = true;
209 uNetmasklengthv6 = ValueUnion.u8;
210 break;
[17759]211 case VINF_GETOPT_NOT_OPTION:
[56118]212 if (pszName)
213 return errorSyntax(USAGE_HOSTONLYIFS, "Only one interface name can be specified");
214 pszName = ValueUnion.psz;
215 break;
[17488]216 default:
[56118]217 return errorGetOpt(USAGE_HOSTONLYIFS, c, &ValueUnion);
[17488]218 }
219 }
220
[18108]221 /* parameter sanity check */
[56118]222 if (fDhcp && (fNetmasklengthv6 || pszIpv6 || pszIp || pszNetmask))
[18108]223 return errorSyntax(USAGE_HOSTONLYIFS, "You can not use --dhcp with static ip configuration parameters: --ip, --netmask, --ipv6 and --netmasklengthv6.");
[56118]224 if ((pszIp || pszNetmask) && (fNetmasklengthv6 || pszIpv6))
[18108]225 return errorSyntax(USAGE_HOSTONLYIFS, "You can not use ipv4 configuration (--ip and --netmask) with ipv6 (--ipv6 and --netmasklengthv6) simultaneously.");
226
[17488]227 ComPtr<IHost> host;
[56118]228 CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
[17488]229
230 ComPtr<IHostNetworkInterface> hif;
[56118]231 CHECK_ERROR2I_RET(host, FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam()), RTEXITCODE_FAILURE);
232 if (hif.isNull())
233 return errorArgument("Could not find interface '%s'", pszName);
[17488]234
[56118]235 if (fDhcp)
236 CHECK_ERROR2I_RET(hif, EnableDynamicIPConfig(), RTEXITCODE_FAILURE);
237 else if (pszIp)
[17488]238 {
[56118]239 if (!pszNetmask)
240 pszNetmask = "255.255.255.0"; /* ?? */
241 CHECK_ERROR2I_RET(hif, EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw()), RTEXITCODE_FAILURE);
[17488]242 }
[56118]243 else if (pszIpv6)
[17488]244 {
[56118]245 BOOL fIpV6Supported;
246 CHECK_ERROR2I_RET(hif, COMGETTER(IPV6Supported)(&fIpV6Supported), RTEXITCODE_FAILURE);
247 if (!fIpV6Supported)
[17759]248 {
[32701]249 RTMsgError("IPv6 setting is not supported for this adapter");
[56118]250 return RTEXITCODE_FAILURE;
[17759]251 }
252
[56118]253 if (uNetmasklengthv6 == UINT32_MAX)
254 uNetmasklengthv6 = 64; /* ?? */
255 CHECK_ERROR2I_RET(hif, EnableStaticIPConfigV6(Bstr(pszIpv6).raw(), (ULONG)uNetmasklengthv6), RTEXITCODE_FAILURE);
[17488]256 }
257 else
[56118]258 return errorSyntax(USAGE_HOSTONLYIFS, "Neither -dhcp nor -ip nor -ipv6 was specfified");
[17488]259
[56118]260 return RTEXITCODE_SUCCESS;
[17488]261}
262
263
[56118]264RTEXITCODE handleHostonlyIf(HandlerArg *a)
[17488]265{
266 if (a->argc < 1)
[56118]267 return errorSyntax(USAGE_HOSTONLYIFS, "No sub-command specified");
[17488]268
[56118]269 RTEXITCODE rcExit;
270 if (!strcmp(a->argv[0], "ipconfig"))
271 rcExit = handleIpConfig(a);
[35317]272#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
[56118]273 else if (!strcmp(a->argv[0], "create"))
274 rcExit = handleCreate(a);
275 else if (!strcmp(a->argv[0], "remove"))
276 rcExit = handleRemove(a);
[17488]277#endif
[56118]278 else
279 rcExit = errorSyntax(USAGE_HOSTONLYIFS, "Unknown sub-command '%s'", a->argv[0]);
280 return rcExit;
[17488]281}
282
283#endif /* !VBOX_ONLY_DOCS */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use