VirtualBox

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

Last change on this file since 67954 was 65827, checked in by vboxsync, 8 years ago

VBoxManage: added --machinereadable option to 'VBoxManage hostonlyif create' (thanks Sara Golemon)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1/* $Id: VBoxManageHostonly.cpp 65827 2017-02-21 08:49:45Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of hostonlyif command.
4 */
5
6/*
7 * Copyright (C) 2006-2016 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 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 }
96
97 Bstr bstrName;
98 CHECK_ERROR2I(hif, COMGETTER(Name)(bstrName.asOutParam()));
99
100 if (fMachineReadable)
101 RTPrintf("%ls", bstrName.raw());
102 else
103 RTPrintf("Interface '%ls' was successfully created\n", bstrName.raw());
104 return RTEXITCODE_SUCCESS;
105}
106
107static RTEXITCODE handleRemove(HandlerArg *a)
108{
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;
125
126 default:
127 return errorGetOpt(USAGE_HOSTONLYIFS, ch, &ValueUnion);
128 }
129 if (!pszName)
130 return errorSyntax(USAGE_HOSTONLYIFS, "No interface name was specified");
131
132 /*
133 * Do the work.
134 */
135 ComPtr<IHost> host;
136 CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
137
138 ComPtr<IHostNetworkInterface> hif;
139 CHECK_ERROR2I_RET(host, FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam()), RTEXITCODE_FAILURE);
140
141 Bstr guid;
142 CHECK_ERROR2I_RET(hif, COMGETTER(Id)(guid.asOutParam()), RTEXITCODE_FAILURE);
143
144 ComPtr<IProgress> progress;
145 CHECK_ERROR2I_RET(host, RemoveHostOnlyNetworkInterface(guid.raw(), progress.asOutParam()), RTEXITCODE_FAILURE);
146
147 /*HRESULT hrc =*/ showProgress(progress);
148 CHECK_PROGRESS_ERROR_RET(progress, ("Failed to remove the host-only adapter"), RTEXITCODE_FAILURE);
149
150 return RTEXITCODE_SUCCESS;
151}
152#endif
153
154static const RTGETOPTDEF g_aHostOnlyIPOptions[]
155 = {
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
166 };
167
168static RTEXITCODE handleIpConfig(HandlerArg *a)
169{
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;
177
178 int c;
179 RTGETOPTUNION ValueUnion;
180 RTGETOPTSTATE GetState;
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)
184 {
185 switch (c)
186 {
187 case 'd': // --dhcp
188 fDhcp = true;
189 break;
190 case 'a': // --ip
191 if (pszIp)
192 RTMsgWarning("The --ip option is specified more than once");
193 pszIp = ValueUnion.psz;
194 break;
195 case 'm': // --netmask
196 if (pszNetmask)
197 RTMsgWarning("The --netmask option is specified more than once");
198 pszNetmask = ValueUnion.psz;
199 break;
200 case 'b': // --ipv6
201 if (pszIpv6)
202 RTMsgWarning("The --ipv6 option is specified more than once");
203 pszIpv6 = ValueUnion.psz;
204 break;
205 case 'l': // --netmasklengthv6
206 if (fNetmasklengthv6)
207 RTMsgWarning("The --netmasklengthv6 option is specified more than once");
208 fNetmasklengthv6 = true;
209 uNetmasklengthv6 = ValueUnion.u8;
210 break;
211 case VINF_GETOPT_NOT_OPTION:
212 if (pszName)
213 return errorSyntax(USAGE_HOSTONLYIFS, "Only one interface name can be specified");
214 pszName = ValueUnion.psz;
215 break;
216 default:
217 return errorGetOpt(USAGE_HOSTONLYIFS, c, &ValueUnion);
218 }
219 }
220
221 /* parameter sanity check */
222 if (fDhcp && (fNetmasklengthv6 || pszIpv6 || pszIp || pszNetmask))
223 return errorSyntax(USAGE_HOSTONLYIFS, "You can not use --dhcp with static ip configuration parameters: --ip, --netmask, --ipv6 and --netmasklengthv6.");
224 if ((pszIp || pszNetmask) && (fNetmasklengthv6 || pszIpv6))
225 return errorSyntax(USAGE_HOSTONLYIFS, "You can not use ipv4 configuration (--ip and --netmask) with ipv6 (--ipv6 and --netmasklengthv6) simultaneously.");
226
227 ComPtr<IHost> host;
228 CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
229
230 ComPtr<IHostNetworkInterface> hif;
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);
234
235 if (fDhcp)
236 CHECK_ERROR2I_RET(hif, EnableDynamicIPConfig(), RTEXITCODE_FAILURE);
237 else if (pszIp)
238 {
239 if (!pszNetmask)
240 pszNetmask = "255.255.255.0"; /* ?? */
241 CHECK_ERROR2I_RET(hif, EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw()), RTEXITCODE_FAILURE);
242 }
243 else if (pszIpv6)
244 {
245 BOOL fIpV6Supported;
246 CHECK_ERROR2I_RET(hif, COMGETTER(IPV6Supported)(&fIpV6Supported), RTEXITCODE_FAILURE);
247 if (!fIpV6Supported)
248 {
249 RTMsgError("IPv6 setting is not supported for this adapter");
250 return RTEXITCODE_FAILURE;
251 }
252
253 if (uNetmasklengthv6 == UINT32_MAX)
254 uNetmasklengthv6 = 64; /* ?? */
255 CHECK_ERROR2I_RET(hif, EnableStaticIPConfigV6(Bstr(pszIpv6).raw(), (ULONG)uNetmasklengthv6), RTEXITCODE_FAILURE);
256 }
257 else
258 return errorSyntax(USAGE_HOSTONLYIFS, "Neither -dhcp nor -ip nor -ipv6 was specfified");
259
260 return RTEXITCODE_SUCCESS;
261}
262
263
264RTEXITCODE handleHostonlyIf(HandlerArg *a)
265{
266 if (a->argc < 1)
267 return errorSyntax(USAGE_HOSTONLYIFS, "No sub-command specified");
268
269 RTEXITCODE rcExit;
270 if (!strcmp(a->argv[0], "ipconfig"))
271 rcExit = handleIpConfig(a);
272#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
273 else if (!strcmp(a->argv[0], "create"))
274 rcExit = handleCreate(a);
275 else if (!strcmp(a->argv[0], "remove"))
276 rcExit = handleRemove(a);
277#endif
278 else
279 rcExit = errorSyntax(USAGE_HOSTONLYIFS, "Unknown sub-command '%s'", a->argv[0]);
280 return rcExit;
281}
282
283#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