e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync/* $Id$ */
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync/** @file
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * VBoxManage - Implementation of NAT Network command command.
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync */
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync/*
a0a3a26a4065b9401681a8c99a11bd83e08f94ccvboxsync * Copyright (C) 2006-2013 Oracle Corporation
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync *
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * available from http://www.virtualbox.org. This file is free software;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * General Public License (GPL) as published by the Free Software
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync */
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync/*******************************************************************************
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync* Header Files *
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync*******************************************************************************/
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#ifndef VBOX_ONLY_DOCS
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <VBox/com/com.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <VBox/com/array.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <VBox/com/ErrorInfo.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <VBox/com/errorprint.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <VBox/com/VirtualBox.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#endif /* !VBOX_ONLY_DOCS */
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
01ae4433227141e4e4782116adae9f6bc287c8b8vboxsync#ifndef RT_OS_WINDOWS
01ae4433227141e4e4782116adae9f6bc287c8b8vboxsync# include <netinet/in.h>
2050786855059bc194ff2314a212acb91f36a516vboxsync#else
2050786855059bc194ff2314a212acb91f36a516vboxsync/* from <ws2ipdef.h> */
2050786855059bc194ff2314a212acb91f36a516vboxsync# define INET6_ADDRSTRLEN 65
01ae4433227141e4e4782116adae9f6bc287c8b8vboxsync#endif
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync#define IPv6
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync#include <iprt/cdefs.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/cidr.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/param.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/path.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/stream.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/string.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/net.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/getopt.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <iprt/ctype.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include <VBox/log.h>
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync#include <vector>
63754a9ea73e5a586fef56e9085955a296342b4evboxsync#include <string>
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#include "VBoxManage.h"
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync#include "VBoxPortForwardString.h"
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#ifndef VBOX_ONLY_DOCS
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsyncusing namespace com;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsynctypedef enum enMainOpCodes
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync{
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync OP_ADD = 1000,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync OP_REMOVE,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync OP_MODIFY,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync OP_START,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync OP_STOP
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync} OPCODE;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsyncstatic const RTGETOPTDEF g_aNATNetworkIPOptions[]
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync = {
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync { "--netname", 't', RTGETOPT_REQ_STRING },
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync { "--network", 'n', RTGETOPT_REQ_STRING },
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync { "--dhcp", 'h', RTGETOPT_REQ_BOOL },
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync { "--ipv6", '6', RTGETOPT_REQ_BOOL},
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync { "--enable", 'e', RTGETOPT_REQ_NOTHING },
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync { "--disable", 'd', RTGETOPT_REQ_NOTHING },
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync { "--port-forward-4", 'p', RTGETOPT_REQ_STRING },
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync { "--port-forward-6", 'P', RTGETOPT_REQ_STRING },
63754a9ea73e5a586fef56e9085955a296342b4evboxsync { "--loopback-4", 'l', RTGETOPT_REQ_STRING },
63754a9ea73e5a586fef56e9085955a296342b4evboxsync { "--loopback-6", 'L', RTGETOPT_REQ_STRING },
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync };
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsynctypedef struct PFNAME2DELETE
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync{
6c91bb6da5c5e29d15700a6f6da6c88463247a9fvboxsync char szName[PF_NAMELEN];
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync bool fIPv6;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync} PFNAME2DELETE, *PPFNAME2DELETE;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsynctypedef std::vector<PFNAME2DELETE> VPF2DELETE;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsynctypedef VPF2DELETE::const_iterator VPF2DELETEITERATOR;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsynctypedef std::vector<PORTFORWARDRULE> VPF2ADD;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsynctypedef VPF2ADD::const_iterator VPF2ADDITERATOR;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
63754a9ea73e5a586fef56e9085955a296342b4evboxsynctypedef std::vector<std::string> LOOPBACK2DELETEADD;
63754a9ea73e5a586fef56e9085955a296342b4evboxsynctypedef LOOPBACK2DELETEADD::iterator LOOPBACK2DELETEADDITERATOR;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsyncstatic int handleOp(HandlerArg *a, OPCODE enmCode, int iStart, int *pcProcessed)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync{
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (a->argc - iStart < 2)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorSyntax(USAGE_NATNETWORK, "Not enough parameters");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int index = iStart;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync HRESULT rc;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync const char *pNetName = NULL;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync const char *pNetworkCidr = NULL;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int enable = -1;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int dhcp = -1;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int ipv6 = -1;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync VPF2DELETE vPfName2Delete;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync VPF2ADD vPf2Add;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
63754a9ea73e5a586fef56e9085955a296342b4evboxsync LOOPBACK2DELETEADD vLoopback2Delete;
63754a9ea73e5a586fef56e9085955a296342b4evboxsync LOOPBACK2DELETEADD vLoopback2Add;
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
63754a9ea73e5a586fef56e9085955a296342b4evboxsync LONG loopback6Offset = 0; /* ignore me */
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int c;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync RTGETOPTUNION ValueUnion;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync RTGETOPTSTATE GetState;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync RTGetOptInit(&GetState,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync a->argc,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync a->argv,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync g_aNATNetworkIPOptions,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync enmCode != OP_REMOVE ? RT_ELEMENTS(g_aNATNetworkIPOptions) : 4, /* we use only --netname and --ifname for remove*/
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync index,
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync RTGETOPTINIT_FLAGS_NO_STD_OPTS);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync while ((c = RTGetOpt(&GetState, &ValueUnion)))
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync {
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync switch (c)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync {
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case 't': // --netname
583173b77380561c8da0cd4960b9a217ea2b7bd7vboxsync if (pNetName)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK, "You can only specify --netname only once.");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync pNetName = ValueUnion.psz;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case 'n': // --network
583173b77380561c8da0cd4960b9a217ea2b7bd7vboxsync if (pNetworkCidr)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK, "You can only specify --network only once.");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync pNetworkCidr = ValueUnion.psz;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case 'e': // --enable
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (enable >= 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorSyntax(USAGE_NATNETWORK, "You can specify either --enable or --disable once.");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync enable = 1;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case 'd': // --disable
583173b77380561c8da0cd4960b9a217ea2b7bd7vboxsync if (enable >= 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorSyntax(USAGE_NATNETWORK, "You can specify either --enable or --disable once.");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync enable = 0;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case 'h':
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (dhcp != -1)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK, "You can specify --dhcp only once.");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync dhcp = ValueUnion.f;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync break;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case '6':
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (ipv6 != -1)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK, "You can specify --ipv6 only once.");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync ipv6 = ValueUnion.f;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync break;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync case 'L': /* ipv6 loopback */
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync case 'l': /* ipv4 loopback */
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync if (RTStrCmp(ValueUnion.psz, "delete") == 0)
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync {
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync /* deletion */
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync if (enmCode != OP_MODIFY)
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync errorSyntax(USAGE_NATNETWORK,
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync "loopback couldn't be deleted on modified\n");
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync if (c == 'L')
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync loopback6Offset = -1;
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync else
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync {
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync int vrc;
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync RTGETOPTUNION Addr2Delete;
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync vrc = RTGetOptFetchValue(&GetState,
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync &Addr2Delete,
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync RTGETOPT_REQ_STRING);
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync if (RT_FAILURE(vrc))
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync return errorSyntax(USAGE_NATNETWORK,
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync "Not enough parmaters\n");
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync vLoopback2Delete.push_back(std::string(Addr2Delete.psz));
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync }
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync }
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync else /* addition */
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync {
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync if (c == 'L')
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync loopback6Offset = ValueUnion.u32;
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync else
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync vLoopback2Add.push_back(std::string(ValueUnion.psz));
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync }
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync break;
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync case 'P': /* ipv6 portforwarding*/
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync case 'p': /* ipv4 portforwarding */
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync {
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync if (RTStrCmp(ValueUnion.psz, "delete") != 0)
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync {
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync PORTFORWARDRULE Pfr;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync /* netPfStrToPf will clean up the Pfr */
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync int irc = netPfStrToPf(ValueUnion.psz, (c == 'P'), &Pfr);
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync if (RT_FAILURE(irc))
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "Invalid port-forward rule %s\n",
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync ValueUnion.psz);
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync vPf2Add.push_back(Pfr);
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync else
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync {
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync int vrc;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync RTGETOPTUNION NamePf2DeleteUnion;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync PFNAME2DELETE Name2Delete;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync if (enmCode != OP_MODIFY)
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "Port-forward could be deleted on modify \n");
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync vrc = RTGetOptFetchValue(&GetState,
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync &NamePf2DeleteUnion,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync RTGETOPT_REQ_STRING);
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync if (RT_FAILURE(vrc))
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "Not enough parmaters\n");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync if (strlen(NamePf2DeleteUnion.psz) > PF_NAMELEN)
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "Port-forward rule name is too long\n");
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync RT_ZERO(Name2Delete);
6c91bb6da5c5e29d15700a6f6da6c88463247a9fvboxsync RTStrCopy(Name2Delete.szName, PF_NAMELEN, NamePf2DeleteUnion.psz);
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync Name2Delete.fIPv6 = (c == 'P');
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync vPfName2Delete.push_back(Name2Delete);
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync break;
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync case VINF_GETOPT_NOT_OPTION:
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync "unhandled parameter: %s",
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync ValueUnion.psz);
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync default:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (c > 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync {
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (RT_C_IS_GRAPH(c))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "unhandled option: -%c", c);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "unhandled option: %i", c);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (c == VERR_GETOPT_UNKNOWN_OPTION)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "unknown option: %s", ValueUnion.psz);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (ValueUnion.pDef)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync "%s: %Rrs", ValueUnion.pDef->pszLong, c);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorSyntax(USAGE_NATNETWORK, "%Rrs", c);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (!pNetName)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync "You need to specify the --netname option");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync /* verification */
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync switch (enmCode)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync {
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case OP_ADD:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (!pNetworkCidr)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorSyntax(USAGE_NATNETWORK,
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync "You need to specify the --network option");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync break;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case OP_MODIFY:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case OP_REMOVE:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case OP_START:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync case OP_STOP:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync break;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync default:
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync AssertMsgFailedReturn(("Unknown operation (:%d)", enmCode), VERR_NOT_IMPLEMENTED);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync Bstr NetName;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync NetName = Bstr(pNetName);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync ComPtr<INATNetwork> net;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync rc = a->virtualBox->FindNATNetworkByName(NetName.mutableRaw(), net.asOutParam());
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (enmCode == OP_ADD)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync {
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (SUCCEEDED(rc))
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorArgument("NATNetwork server already exists");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync CHECK_ERROR(a->virtualBox, CreateNATNetwork(NetName.raw(), net.asOutParam()));
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (FAILED(rc))
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorArgument("Failed to create the NAT network service");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (FAILED(rc))
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorArgument("NATNetwork server does not exist");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync switch (enmCode)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync case OP_ADD:
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync case OP_MODIFY:
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (pNetworkCidr)
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, COMSETTER(Network)(Bstr(pNetworkCidr).raw()));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to set configuration");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (dhcp >= 0)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, COMSETTER(NeedDhcpServer) ((BOOL)dhcp));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to set configuration");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (ipv6 >= 0)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, COMSETTER(IPv6Enabled) ((BOOL)ipv6));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to set configuration");
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (!vPfName2Delete.empty())
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync VPF2DELETEITERATOR it;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync for (it = vPfName2Delete.begin(); it != vPfName2Delete.end(); ++it)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, RemovePortForwardRule((BOOL)(*it).fIPv6,
6c91bb6da5c5e29d15700a6f6da6c88463247a9fvboxsync Bstr((*it).szName).raw()));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to delete pf");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (!vPf2Add.empty())
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync VPF2ADDITERATOR it;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync for (it = vPf2Add.begin(); it != vPf2Add.end(); ++it)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync NATProtocol_T proto = NATProtocol_TCP;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if ((*it).iPfrProto == IPPROTO_TCP)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync proto = NATProtocol_TCP;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync else if ((*it).iPfrProto == IPPROTO_UDP)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync proto = NATProtocol_UDP;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync else
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync continue; /* XXX: warning here. */
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, AddPortForwardRule((BOOL)(*it).fPfrIPv6,
6c91bb6da5c5e29d15700a6f6da6c88463247a9fvboxsync Bstr((*it).szPfrName).raw(),
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync proto,
6c91bb6da5c5e29d15700a6f6da6c88463247a9fvboxsync Bstr((*it).szPfrHostAddr).raw(),
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync (*it).u16PfrHostPort,
6c91bb6da5c5e29d15700a6f6da6c88463247a9fvboxsync Bstr((*it).szPfrGuestAddr).raw(),
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync (*it).u16PfrGuestPort));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to add pf");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (loopback6Offset)
63754a9ea73e5a586fef56e9085955a296342b4evboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (loopback6Offset == -1)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync loopback6Offset = 0; /* deletion */
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR_RET(net, COMSETTER(LoopbackIp6)(loopback6Offset), rc);
63754a9ea73e5a586fef56e9085955a296342b4evboxsync }
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync /* addLocalMapping (hostid, offset) */
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (!vLoopback2Add.empty())
63754a9ea73e5a586fef56e9085955a296342b4evboxsync {
d32ee79929c09a2d5c985ed48c93385e9e0ee28avboxsync /* we're expecting stings 127.0.0.1=5 */
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync LOOPBACK2DELETEADDITERATOR it;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync for (it = vLoopback2Add.begin();
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync it != vLoopback2Add.end();
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync ++it)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync std::string address, strOffset;
e5b0208675ead20da446a0a114cb9f76babf5e11vboxsync size_t pos = it->find('=');
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync LONG lOffset = 0;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync Bstr bstrAddress;
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
613def9d08d016040064cf7ac3033589004f8209vboxsync AssertReturn(pos != std::string::npos, errorArgument("invalid loopback string"));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync address = it->substr(0, pos);
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync strOffset = it->substr(pos + 1);
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync lOffset = RTStrToUInt32(strOffset.c_str());
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync AssertReturn(lOffset > 0, errorArgument("invalid loopback string"));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync bstrAddress = Bstr(address.c_str());
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR_RET(net, AddLocalMapping(bstrAddress.raw(), lOffset), rc);
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
63754a9ea73e5a586fef56e9085955a296342b4evboxsync }
63754a9ea73e5a586fef56e9085955a296342b4evboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (!vLoopback2Delete.empty())
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync /* we're expecting stings 127.0.0.1 */
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync LOOPBACK2DELETEADDITERATOR it;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync for (it = vLoopback2Add.begin();
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync it != vLoopback2Add.end();
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync ++it)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync Bstr bstrAddress;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync bstrAddress = Bstr(it->c_str());
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR_RET(net, AddLocalMapping(bstrAddress.raw(), 0), rc);
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (enable >= 0)
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, COMSETTER(Enabled) ((BOOL)enable));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to set configuration");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync case OP_REMOVE:
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(a->virtualBox, RemoveNATNetwork(net));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to remove nat network");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync case OP_START:
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, Start(Bstr("whatever").raw()));
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to start network");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync case OP_STOP:
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync {
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync CHECK_ERROR(net, Stop());
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync if (FAILED(rc))
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync return errorArgument("Failed to start network");
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync break;
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync }
6eb65b2eefabe4acca6c24bd794075aeb605872fvboxsync default:;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync }
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return 0;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync}
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsyncint handleNATNetwork(HandlerArg *a)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync{
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (a->argc < 1)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return errorSyntax(USAGE_NATNETWORK, "Not enough parameters");
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int result;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync int cProcessed;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync if (strcmp(a->argv[0], "modify") == 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync result = handleOp(a, OP_MODIFY, 1, &cProcessed);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (strcmp(a->argv[0], "add") == 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync result = handleOp(a, OP_ADD, 1, &cProcessed);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (strcmp(a->argv[0], "remove") == 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync result = handleOp(a, OP_REMOVE, 1, &cProcessed);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (strcmp(a->argv[0], "start") == 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync result = handleOp(a, OP_START, 1, &cProcessed);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else if (strcmp(a->argv[0], "stop") == 0)
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync result = handleOp(a, OP_STOP, 1, &cProcessed);
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync else
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync result = errorSyntax(USAGE_NATNETWORK, "Invalid parameter '%s'", Utf8Str(a->argv[0]).c_str());
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync return result;
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync}
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync
e7668566fb8c8659f002fc6b55692bd52a4b3ac4vboxsync#endif /* !VBOX_ONLY_DOCS */