VirtualBox

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

Last change on this file since 18227 was 18108, checked in by vboxsync, 16 years ago

VBoxManage: clean up various places which use RTGetOpt, fix error handling to deal with changed RTGetOpt semantics, make the double-dash options the recommended ones, updated help

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