VirtualBox

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

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

Copyright year updates by scm.

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

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