VirtualBox

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

Last change on this file since 46845 was 46658, checked in by vboxsync, 12 years ago

include VBox/com/EventQueue only if necessary

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