VirtualBox

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

Last change on this file since 29607 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

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