VirtualBox

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

Last change on this file since 18725 was 18323, checked in by vboxsync, 16 years ago

DHCP server/win: make it work again; NetFlt,Adp/win: IDC init polling

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