VirtualBox

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

Last change on this file since 37763 was 35330, checked in by vboxsync, 14 years ago

VBoxManage: fixed segmentation fault when removing non-existent host-only interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/* $Id: VBoxManageHostonly.cpp 35330 2010-12-24 18:05:33Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of hostonlyif command.
4 */
5
6/*
7 * Copyright (C) 2006-2010 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* Header Files *
20*******************************************************************************/
21#ifndef VBOX_ONLY_DOCS
22#include <VBox/com/com.h>
23#include <VBox/com/array.h>
24#include <VBox/com/ErrorInfo.h>
25#include <VBox/com/errorprint.h>
26#include <VBox/com/EventQueue.h>
27
28#include <VBox/com/VirtualBox.h>
29#endif /* !VBOX_ONLY_DOCS */
30
31#include <iprt/cidr.h>
32#include <iprt/param.h>
33#include <iprt/path.h>
34#include <iprt/stream.h>
35#include <iprt/string.h>
36#include <iprt/net.h>
37#include <iprt/getopt.h>
38#include <iprt/ctype.h>
39
40#include <VBox/log.h>
41
42#include "VBoxManage.h"
43
44#ifndef VBOX_ONLY_DOCS
45using namespace com;
46
47#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
48static int handleCreate(HandlerArg *a, int iStart, int *pcProcessed)
49{
50// if (a->argc - iStart < 1)
51// return errorSyntax(USAGE_HOSTONLYIFS, "Not enough parameters");
52
53 int index = iStart;
54 HRESULT rc;
55// Bstr name(a->argv[iStart]);
56// index++;
57
58 ComPtr<IHost> host;
59 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
60
61 ComPtr<IHostNetworkInterface> hif;
62 ComPtr<IProgress> progress;
63
64 CHECK_ERROR(host, CreateHostOnlyNetworkInterface (hif.asOutParam(), progress.asOutParam()));
65
66 rc = showProgress(progress);
67 *pcProcessed = index - iStart;
68 if (FAILED(rc))
69 {
70 com::ProgressErrorInfo info(progress);
71 if (info.isBasicAvailable())
72 RTMsgError("Failed to create the host-only adapter. Error message: %lS", info.getText().raw());
73 else
74 RTMsgError("Failed to create the host-only adapter. No error message available, code: %Rhrc", rc);
75
76 return 1;
77 }
78
79 Bstr name;
80 CHECK_ERROR(hif, COMGETTER(Name) (name.asOutParam()));
81
82 RTPrintf("Interface '%lS' was successfully created\n", name.raw());
83
84 return 0;
85}
86
87static int handleRemove(HandlerArg *a, int iStart, int *pcProcessed)
88{
89 if (a->argc - iStart < 1)
90 return errorSyntax(USAGE_HOSTONLYIFS, "Not enough parameters");
91
92 int index = iStart;
93 HRESULT rc;
94
95 Bstr name(a->argv[iStart]);
96 index++;
97
98 ComPtr<IHost> host;
99 CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), 1);
100
101 ComPtr<IHostNetworkInterface> hif;
102 CHECK_ERROR_RET(host, FindHostNetworkInterfaceByName(name.raw(), hif.asOutParam()), 1);
103
104 Bstr guid;
105 CHECK_ERROR_RET(hif, COMGETTER(Id)(guid.asOutParam()), 1);
106
107 ComPtr<IProgress> progress;
108 CHECK_ERROR_RET(host, RemoveHostOnlyNetworkInterface(guid.raw(), progress.asOutParam()), 1);
109
110 rc = showProgress(progress);
111 *pcProcessed = index - iStart;
112 if (FAILED(rc))
113 {
114 com::ProgressErrorInfo info(progress);
115 if (info.isBasicAvailable())
116 RTMsgError("Failed to remove the host-only adapter. Error message: %lS", info.getText().raw());
117 else
118 RTMsgError("Failed to remove the host-only adapter. No error message available, code: %Rhrc", rc);
119
120 return 1;
121 }
122
123 return 0;
124}
125#endif
126
127static const RTGETOPTDEF g_aHostOnlyIPOptions[]
128 = {
129 { "--dhcp", 'd', RTGETOPT_REQ_NOTHING },
130 { "-dhcp", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
131 { "--ip", 'a', RTGETOPT_REQ_STRING },
132 { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated
133 { "--netmask", 'm', RTGETOPT_REQ_STRING },
134 { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated
135 { "--ipv6", 'b', RTGETOPT_REQ_STRING },
136 { "-ipv6", 'b', RTGETOPT_REQ_STRING }, // deprecated
137 { "--netmasklengthv6", 'l', RTGETOPT_REQ_UINT8 },
138 { "-netmasklengthv6", 'l', RTGETOPT_REQ_UINT8 } // deprecated
139 };
140
141static int handleIpconfig(HandlerArg *a, int iStart, int *pcProcessed)
142{
143 if (a->argc - iStart < 2)
144 return errorSyntax(USAGE_HOSTONLYIFS, "Not enough parameters");
145
146 int index = iStart;
147 HRESULT rc;
148
149 Bstr name(a->argv[iStart]);
150 index++;
151
152 bool bDhcp = false;
153 bool bNetmasklengthv6 = false;
154 uint32_t uNetmasklengthv6 = (uint32_t)-1;
155 const char *pIpv6 = NULL;
156 const char *pIp = NULL;
157 const char *pNetmask = NULL;
158
159 int c;
160 RTGETOPTUNION ValueUnion;
161 RTGETOPTSTATE GetState;
162 RTGetOptInit(&GetState,
163 a->argc,
164 a->argv,
165 g_aHostOnlyIPOptions,
166 RT_ELEMENTS(g_aHostOnlyIPOptions),
167 index,
168 RTGETOPTINIT_FLAGS_NO_STD_OPTS);
169 while ((c = RTGetOpt(&GetState, &ValueUnion)))
170 {
171 switch (c)
172 {
173 case 'd': // --dhcp
174 if (bDhcp)
175 return errorSyntax(USAGE_HOSTONLYIFS, "You can only specify --dhcp once.");
176 else
177 bDhcp = true;
178 break;
179 case 'a': // --ip
180 if(pIp)
181 return errorSyntax(USAGE_HOSTONLYIFS, "You can only specify --ip once.");
182 else
183 pIp = ValueUnion.psz;
184 break;
185 case 'm': // --netmask
186 if(pNetmask)
187 return errorSyntax(USAGE_HOSTONLYIFS, "You can only specify --netmask once.");
188 else
189 pNetmask = ValueUnion.psz;
190 break;
191 case 'b': // --ipv6
192 if(pIpv6)
193 return errorSyntax(USAGE_HOSTONLYIFS, "You can only specify --ipv6 once.");
194 else
195 pIpv6 = ValueUnion.psz;
196 break;
197 case 'l': // --netmasklengthv6
198 if(bNetmasklengthv6)
199 return errorSyntax(USAGE_HOSTONLYIFS, "You can only specify --netmasklengthv6 once.");
200 else
201 {
202 bNetmasklengthv6 = true;
203 uNetmasklengthv6 = ValueUnion.u8;
204 }
205 break;
206 case VINF_GETOPT_NOT_OPTION:
207 return errorSyntax(USAGE_HOSTONLYIFS, "unhandled parameter: %s", ValueUnion.psz);
208 break;
209 default:
210 if (c > 0)
211 {
212 if (RT_C_IS_GRAPH(c))
213 return errorSyntax(USAGE_HOSTONLYIFS, "unhandled option: -%c", c);
214 else
215 return errorSyntax(USAGE_HOSTONLYIFS, "unhandled option: %i", c);
216 }
217 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
218 return errorSyntax(USAGE_HOSTONLYIFS, "unknown option: %s", ValueUnion.psz);
219 else if (ValueUnion.pDef)
220 return errorSyntax(USAGE_HOSTONLYIFS, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
221 else
222 return errorSyntax(USAGE_HOSTONLYIFS, "%Rrs", c);
223 }
224 }
225
226 /* parameter sanity check */
227 if (bDhcp && (bNetmasklengthv6 || pIpv6 || pIp || pNetmask))
228 return errorSyntax(USAGE_HOSTONLYIFS, "You can not use --dhcp with static ip configuration parameters: --ip, --netmask, --ipv6 and --netmasklengthv6.");
229 if((pIp || pNetmask) && (bNetmasklengthv6 || pIpv6))
230 return errorSyntax(USAGE_HOSTONLYIFS, "You can not use ipv4 configuration (--ip and --netmask) with ipv6 (--ipv6 and --netmasklengthv6) simultaneously.");
231
232 ComPtr<IHost> host;
233 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
234
235 ComPtr<IHostNetworkInterface> hif;
236 CHECK_ERROR(host, FindHostNetworkInterfaceByName(name.raw(),
237 hif.asOutParam()));
238
239 if (FAILED(rc))
240 return errorArgument("Could not find interface '%s'", a->argv[iStart]);
241
242 if (bDhcp)
243 {
244 CHECK_ERROR(hif, EnableDynamicIpConfig ());
245 }
246 else if (pIp)
247 {
248 if (!pNetmask)
249 pNetmask = "255.255.255.0"; /* ?? */
250
251 CHECK_ERROR(hif, EnableStaticIpConfig(Bstr(pIp).raw(),
252 Bstr(pNetmask).raw()));
253 }
254 else if (pIpv6)
255 {
256 if (uNetmasklengthv6 == (uint32_t)-1)
257 uNetmasklengthv6 = 64; /* ?? */
258
259 BOOL bIpV6Supported;
260 CHECK_ERROR(hif, COMGETTER(IPV6Supported)(&bIpV6Supported));
261 if (!bIpV6Supported)
262 {
263 RTMsgError("IPv6 setting is not supported for this adapter");
264 return 1;
265 }
266
267
268 Bstr ipv6str(pIpv6);
269 CHECK_ERROR(hif, EnableStaticIpConfigV6(ipv6str.raw(),
270 (ULONG)uNetmasklengthv6));
271 }
272 else
273 {
274 return errorSyntax(USAGE_HOSTONLYIFS, "neither -dhcp nor -ip nor -ipv6 was spcfified");
275 }
276
277 return 0;
278}
279
280
281int handleHostonlyIf(HandlerArg *a)
282{
283 int result = 0;
284 if (a->argc < 1)
285 return errorSyntax(USAGE_HOSTONLYIFS, "Not enough parameters");
286
287 for (int i = 0; i < a->argc; i++)
288 {
289 if (strcmp(a->argv[i], "ipconfig") == 0)
290 {
291 int cProcessed;
292 result = handleIpconfig(a, i+1, &cProcessed);
293 break;
294// if(!rc)
295// i+= cProcessed;
296// else
297// break;
298 }
299#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
300 else if (strcmp(a->argv[i], "create") == 0)
301 {
302 int cProcessed;
303 result = handleCreate(a, i+1, &cProcessed);
304 if(!result)
305 i+= cProcessed;
306 else
307 break;
308 }
309 else if (strcmp(a->argv[i], "remove") == 0)
310 {
311 int cProcessed;
312 result = handleRemove(a, i+1, &cProcessed);
313 if(!result)
314 i+= cProcessed;
315 else
316 break;
317 }
318#endif
319 else
320 {
321 result = errorSyntax(USAGE_HOSTONLYIFS, "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str());
322 break;
323 }
324 }
325
326 return result;
327}
328
329#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