VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp@ 33253

Last change on this file since 33253 was 32701, checked in by vboxsync, 14 years ago

Frontends/VBoxManage: Error printing cleanup, use stderr and consistent formatting. Small cleanups (like using Keyboard::PutScancodes instead of the more clumsy Keyboard::PutScancode and fixing the incorrect comment which attracted my attention).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
Line 
1/* $Id: VBoxManageDHCPServer.cpp 32701 2010-09-22 17:12:01Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of dhcpserver 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
47typedef enum enMainOpCodes
48{
49 OP_ADD = 1000,
50 OP_REMOVE,
51 OP_MODIFY
52} OPCODE;
53
54static const RTGETOPTDEF g_aDHCPIPOptions[]
55 = {
56 { "--netname", 't', RTGETOPT_REQ_STRING }, /* we use 't' instead of 'n' to avoid
57 * 1. the misspelled "-enable" long option to be treated as 'e' (for -enable) + 'n' (for -netname) + "<the_rest_opt>" (for net name)
58 * 2. the misspelled "-netmask" to be treated as 'n' (for -netname) + "<the_rest_opt>" (for net name)
59 */
60 { "-netname", 't', RTGETOPT_REQ_STRING }, // deprecated (if removed check below)
61 { "--ifname", 'f', RTGETOPT_REQ_STRING }, /* we use 'f' instead of 'i' to avoid
62 * 1. the misspelled "-disable" long option to be treated as 'd' (for -disable) + 'i' (for -ifname) + "<the_rest_opt>" (for if name)
63 */
64 { "-ifname", 'f', RTGETOPT_REQ_STRING }, // deprecated
65 { "--ip", 'a', RTGETOPT_REQ_STRING },
66 { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated
67 { "--netmask", 'm', RTGETOPT_REQ_STRING },
68 { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated
69 { "--lowerip", 'l', RTGETOPT_REQ_STRING },
70 { "-lowerip", 'l', RTGETOPT_REQ_STRING }, // deprecated
71 { "--upperip", 'u', RTGETOPT_REQ_STRING },
72 { "-upperip", 'u', RTGETOPT_REQ_STRING }, // deprecated
73 { "--enable", 'e', RTGETOPT_REQ_NOTHING },
74 { "-enable", 'e', RTGETOPT_REQ_NOTHING }, // deprecated
75 { "--disable", 'd', RTGETOPT_REQ_NOTHING },
76 { "-disable", 'd', RTGETOPT_REQ_NOTHING } // deprecated
77 };
78
79static int handleOp(HandlerArg *a, OPCODE enmCode, int iStart, int *pcProcessed)
80{
81 if (a->argc - iStart < 2)
82 return errorSyntax(USAGE_DHCPSERVER, "Not enough parameters");
83
84 int index = iStart;
85 HRESULT rc;
86
87 const char *pNetName = NULL;
88 const char *pIfName = NULL;
89 const char * pIp = NULL;
90 const char * pNetmask = NULL;
91 const char * pLowerIp = NULL;
92 const char * pUpperIp = NULL;
93 int enable = -1;
94
95 int c;
96 RTGETOPTUNION ValueUnion;
97 RTGETOPTSTATE GetState;
98 RTGetOptInit(&GetState,
99 a->argc,
100 a->argv,
101 g_aDHCPIPOptions,
102 enmCode != OP_REMOVE ? RT_ELEMENTS(g_aDHCPIPOptions) : 4, /* we use only --netname and --ifname for remove*/
103 index,
104 RTGETOPTINIT_FLAGS_NO_STD_OPTS);
105 while ((c = RTGetOpt(&GetState, &ValueUnion)))
106 {
107 switch (c)
108 {
109 case 't': // --netname
110 if(pNetName)
111 return errorSyntax(USAGE_DHCPSERVER, "You can only specify --netname once.");
112 else if (pIfName)
113 return errorSyntax(USAGE_DHCPSERVER, "You can either use a --netname or --ifname for identifying the DHCP server.");
114 else
115 {
116 pNetName = ValueUnion.psz;
117 }
118 break;
119 case 'f': // --ifname
120 if(pIfName)
121 return errorSyntax(USAGE_DHCPSERVER, "You can only specify --ifname once.");
122 else if (pNetName)
123 return errorSyntax(USAGE_DHCPSERVER, "You can either use a --netname or --ipname for identifying the DHCP server.");
124 else
125 {
126 pIfName = ValueUnion.psz;
127 }
128 break;
129 case 'a': // -ip
130 if(pIp)
131 return errorSyntax(USAGE_DHCPSERVER, "You can only specify --ip once.");
132 else
133 {
134 pIp = ValueUnion.psz;
135 }
136 break;
137 case 'm': // --netmask
138 if(pNetmask)
139 return errorSyntax(USAGE_DHCPSERVER, "You can only specify --netmask once.");
140 else
141 {
142 pNetmask = ValueUnion.psz;
143 }
144 break;
145 case 'l': // --lowerip
146 if(pLowerIp)
147 return errorSyntax(USAGE_DHCPSERVER, "You can only specify --lowerip once.");
148 else
149 {
150 pLowerIp = ValueUnion.psz;
151 }
152 break;
153 case 'u': // --upperip
154 if(pUpperIp)
155 return errorSyntax(USAGE_DHCPSERVER, "You can only specify --upperip once.");
156 else
157 {
158 pUpperIp = ValueUnion.psz;
159 }
160 break;
161 case 'e': // --enable
162 if(enable >= 0)
163 return errorSyntax(USAGE_DHCPSERVER, "You can specify either --enable or --disable once.");
164 else
165 {
166 enable = 1;
167 }
168 break;
169 case 'd': // --disable
170 if(enable >= 0)
171 return errorSyntax(USAGE_DHCPSERVER, "You can specify either --enable or --disable once.");
172 else
173 {
174 enable = 0;
175 }
176 break;
177 case VINF_GETOPT_NOT_OPTION:
178 return errorSyntax(USAGE_DHCPSERVER, "unhandled parameter: %s", ValueUnion.psz);
179 break;
180 default:
181 if (c > 0)
182 {
183 if (RT_C_IS_GRAPH(c))
184 return errorSyntax(USAGE_DHCPSERVER, "unhandled option: -%c", c);
185 else
186 return errorSyntax(USAGE_DHCPSERVER, "unhandled option: %i", c);
187 }
188 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
189 return errorSyntax(USAGE_DHCPSERVER, "unknown option: %s", ValueUnion.psz);
190 else if (ValueUnion.pDef)
191 return errorSyntax(USAGE_DHCPSERVER, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
192 else
193 return errorSyntax(USAGE_DHCPSERVER, "%Rrs", c);
194 }
195 }
196
197 if(! pNetName && !pIfName)
198 return errorSyntax(USAGE_DHCPSERVER, "You need to specify either --netname or --ifname to identify the DHCP server");
199
200 if(enmCode != OP_REMOVE)
201 {
202 if(enable < 0 || pIp || pNetmask || pLowerIp || pUpperIp)
203 {
204 if(!pIp)
205 return errorSyntax(USAGE_DHCPSERVER, "You need to specify --ip option");
206
207 if(!pNetmask)
208 return errorSyntax(USAGE_DHCPSERVER, "You need to specify --netmask option");
209
210 if(!pLowerIp)
211 return errorSyntax(USAGE_DHCPSERVER, "You need to specify --lowerip option");
212
213 if(!pUpperIp)
214 return errorSyntax(USAGE_DHCPSERVER, "You need to specify --upperip option");
215 }
216 }
217
218 Bstr NetName;
219 if(!pNetName)
220 {
221 ComPtr<IHost> host;
222 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
223
224 ComPtr<IHostNetworkInterface> hif;
225 CHECK_ERROR(host, FindHostNetworkInterfaceByName(Bstr(pIfName).mutableRaw(), hif.asOutParam()));
226 if (FAILED(rc))
227 return errorArgument("Could not find interface '%s'", pIfName);
228
229 CHECK_ERROR(hif, COMGETTER(NetworkName) (NetName.asOutParam()));
230 if (FAILED(rc))
231 return errorArgument("Could not get network name for the interface '%s'", pIfName);
232 }
233 else
234 {
235 NetName = Bstr(pNetName);
236 }
237
238 ComPtr<IDHCPServer> svr;
239 rc = a->virtualBox->FindDHCPServerByNetworkName(NetName.mutableRaw(), svr.asOutParam());
240 if(enmCode == OP_ADD)
241 {
242 if (SUCCEEDED(rc))
243 return errorArgument("DHCP server already exists");
244
245 CHECK_ERROR(a->virtualBox, CreateDHCPServer(NetName.mutableRaw(), svr.asOutParam()));
246 if (FAILED(rc))
247 return errorArgument("Failed to create the DHCP server");
248 }
249 else if (FAILED(rc))
250 {
251 return errorArgument("DHCP server does not exist");
252 }
253
254 if(enmCode != OP_REMOVE)
255 {
256 if (pIp || pNetmask || pLowerIp || pUpperIp)
257 {
258 CHECK_ERROR(svr, SetConfiguration (Bstr(pIp).mutableRaw(), Bstr(pNetmask).mutableRaw(), Bstr(pLowerIp).mutableRaw(), Bstr(pUpperIp).mutableRaw()));
259 if(FAILED(rc))
260 return errorArgument("Failed to set configuration");
261 }
262
263 if(enable >= 0)
264 {
265 CHECK_ERROR(svr, COMSETTER(Enabled) ((BOOL)enable));
266 }
267 }
268 else
269 {
270 CHECK_ERROR(a->virtualBox, RemoveDHCPServer(svr));
271 if(FAILED(rc))
272 return errorArgument("Failed to remove server");
273 }
274
275 return 0;
276}
277
278
279int handleDHCPServer(HandlerArg *a)
280{
281 int result = 0;
282 if (a->argc < 1)
283 return errorSyntax(USAGE_DHCPSERVER, "Not enough parameters");
284
285 for (int i = 0; i < a->argc; i++)
286 {
287 if (strcmp(a->argv[i], "modify") == 0)
288 {
289 int cProcessed;
290 result = handleOp(a, OP_MODIFY, i+1, &cProcessed);
291 break;
292 }
293 else if (strcmp(a->argv[i], "add") == 0)
294 {
295 int cProcessed;
296 result = handleOp(a, OP_ADD, i+1, &cProcessed);
297 break;
298 }
299 else if (strcmp(a->argv[i], "remove") == 0)
300 {
301 int cProcessed;
302 result = handleOp(a, OP_REMOVE, i+1, &cProcessed);
303 break;
304 }
305 else
306 {
307 result = errorSyntax(USAGE_DHCPSERVER, "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str());
308 break;
309 }
310 }
311
312 return result;
313}
314
315#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