Index: trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk	(revision 45551)
+++ trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk	(revision 45559)
@@ -56,5 +56,6 @@
 	VBoxManageStorageController.cpp \
 	VBoxManageUSB.cpp \
-	$(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,)
+	$(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,) \
+	$(if $(VBOX_WITH_NAT_SERVICE),../../NetworkServices/NetLib/VBoxNetPortForwardString.cpp,)
 VBoxManage_LIBS      += $(LIB_DDU)
 
@@ -82,4 +83,7 @@
 	$(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE)
 
+# VBoxNetPortForwardString.h
+VBoxManageNATNetwork.cpp_INCS += ../../NetworkServices/NetLib/
+
 ifneq ($(KBUILD_TARGET),win)
  # Workaround for buggy gcc-4.3 compilers, see
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp	(revision 45551)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp	(revision 45559)
@@ -20,4 +20,6 @@
 *******************************************************************************/
 #ifndef VBOX_ONLY_DOCS
+
+
 #include <VBox/com/com.h>
 #include <VBox/com/array.h>
@@ -29,4 +31,9 @@
 #endif /* !VBOX_ONLY_DOCS */
 
+#include <netinet/in.h>
+
+#define IPv6
+
+#include <iprt/cdefs.h>
 #include <iprt/cidr.h>
 #include <iprt/param.h>
@@ -40,7 +47,11 @@
 #include <VBox/log.h>
 
+#include <vector>
+
 #include "VBoxManage.h"
+#include "VBoxPortForwardString.h"
 
 #ifndef VBOX_ONLY_DOCS
+
 using namespace com;
 
@@ -62,6 +73,20 @@
         { "--enable",           'e', RTGETOPT_REQ_NOTHING },
         { "--disable",          'd', RTGETOPT_REQ_NOTHING },
-
+        { "--port-forward-4",   'p', RTGETOPT_REQ_STRING },
+        { "--port-forward-6",   'P', RTGETOPT_REQ_STRING },
       };
+
+typedef struct PFNAME2DELETE
+{
+    char aszName[PF_NAMELEN];
+    bool fIPv6;
+} PFNAME2DELETE, *PPFNAME2DELETE;
+
+typedef std::vector<PFNAME2DELETE> VPF2DELETE;
+typedef VPF2DELETE::const_iterator VPF2DELETEITERATOR;
+
+typedef std::vector<PORTFORWARDRULE> VPF2ADD;
+typedef VPF2ADD::const_iterator VPF2ADDITERATOR;
+
 
 static int handleOp(HandlerArg *a, OPCODE enmCode, int iStart, int *pcProcessed)
@@ -79,7 +104,11 @@
     int ipv6 = -1;
 
+    VPF2DELETE vPfName2Delete;
+    VPF2ADD vPf2Add;
+
     int c;
     RTGETOPTUNION ValueUnion;
     RTGETOPTSTATE GetState;
+
     RTGetOptInit(&GetState,
                  a->argc,
@@ -101,4 +130,5 @@
                 }
             break;
+
             case 'n':   // --network
                 if(pNetworkCidr)
@@ -109,4 +139,5 @@
                 }
             break;
+
             case 'e':   // --enable
                 if(enable >= 0)
@@ -117,4 +148,5 @@
                 }
             break;
+
             case 'd':   // --disable
                 if(enable >= 0)
@@ -125,7 +157,5 @@
                 }
             break;
-            case VINF_GETOPT_NOT_OPTION:
-                return errorSyntax(USAGE_NATNETWORK, "unhandled parameter: %s", ValueUnion.psz);
-            break;
+           
             case 'h':
                 if (dhcp != -1)
@@ -133,4 +163,5 @@
                 dhcp = ValueUnion.f;
                 break;
+
             case '6':
                 if (ipv6 != -1)
@@ -138,16 +169,75 @@
                 ipv6 = ValueUnion.f;
                 break;
+
+            case 'P': /* ipv6 portforwarding*/
+            case 'p': /* ipv4 portforwarding */
+            {
+                if (RTStrCmp(ValueUnion.psz, "delete") != 0)
+                {
+                    PORTFORWARDRULE Pfr;
+
+                    /* netPfStrToPf will clean up the Pfr */
+                    int irc = netPfStrToPf(ValueUnion.psz, (c == 'P'), &Pfr);
+                    if (RT_FAILURE(irc))
+                        return errorSyntax(USAGE_NATNETWORK,
+                                           "Invalid port-forward rule %s\n",
+                                           ValueUnion.psz);
+                    
+                    vPf2Add.push_back(Pfr);
+                }
+                else
+                {
+                    int vrc;
+                    RTGETOPTUNION NamePf2DeleteUnion;
+                    PFNAME2DELETE Name2Delete;
+
+                    if (enmCode != OP_MODIFY)
+                        return errorSyntax(USAGE_NATNETWORK,
+                                           "Port-forward could be deleted on modify \n");
+
+                    vrc = RTGetOptFetchValue(&GetState, 
+                                             &NamePf2DeleteUnion, 
+                                             RTGETOPT_REQ_STRING);
+                    if (RT_FAILURE(vrc))
+                        return errorSyntax(USAGE_NATNETWORK,
+                                           "Not enough parmaters\n");
+                    
+                    if (strlen(NamePf2DeleteUnion.psz) > PF_NAMELEN)
+                        return errorSyntax(USAGE_NATNETWORK,
+                                           "Port-forward rule name is too long\n");
+
+                    RT_ZERO(Name2Delete);
+                    RTStrCopy(Name2Delete.aszName, 
+                              PF_NAMELEN, 
+                              NamePf2DeleteUnion.psz);
+                    Name2Delete.fIPv6 = (c == 'P');
+
+                    vPfName2Delete.push_back(Name2Delete);
+                }
+                break;
+            }
+
+            case VINF_GETOPT_NOT_OPTION:
+                return errorSyntax(USAGE_NATNETWORK, 
+                                   "unhandled parameter: %s", 
+                                   ValueUnion.psz);
+            break;
+
             default:
                 if (c > 0)
                 {
                     if (RT_C_IS_GRAPH(c))
-                        return errorSyntax(USAGE_NATNETWORK, "unhandled option: -%c", c);
+                        return errorSyntax(USAGE_NATNETWORK, 
+                                           "unhandled option: -%c", c);
                     else
-                        return errorSyntax(USAGE_NATNETWORK, "unhandled option: %i", c);
+                        return errorSyntax(USAGE_NATNETWORK, 
+                                           "unhandled option: %i", c);
                 }
                 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
-                    return errorSyntax(USAGE_NATNETWORK, "unknown option: %s", ValueUnion.psz);
+                    return errorSyntax(USAGE_NATNETWORK, 
+                                       "unknown option: %s", ValueUnion.psz);
                 else if (ValueUnion.pDef)
-                    return errorSyntax(USAGE_NATNETWORK, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
+                    return errorSyntax(USAGE_NATNETWORK, 
+                                       "%s: %Rrs", ValueUnion.pDef->pszLong, c);
                 else
                     return errorSyntax(USAGE_NATNETWORK, "%Rrs", c);
@@ -218,4 +308,44 @@
               if(FAILED(rc))
                 return errorArgument("Failed to set configuration");
+        }
+        
+        if (!vPfName2Delete.empty())
+        {
+            VPF2DELETEITERATOR it;
+            for (it = vPfName2Delete.begin(); it != vPfName2Delete.end(); ++it)
+            {
+                CHECK_ERROR(net, RemovePortForwardRule((BOOL)(*it).fIPv6,
+                                                       Bstr((*it).aszName).raw()));
+                if(FAILED(rc))
+                    return errorArgument("Failed to delete pf");
+
+            }
+        }
+
+        if (!vPf2Add.empty())
+        {
+            VPF2ADDITERATOR it;
+            for(it = vPf2Add.begin(); it != vPf2Add.end(); ++it)
+            {
+                NATProtocol_T proto = NATProtocol_TCP;
+                if ((*it).iPfrProto == IPPROTO_TCP)
+                    proto = NATProtocol_TCP;
+                else if ((*it).iPfrProto == IPPROTO_UDP)
+                    proto = NATProtocol_UDP;
+                else
+                    continue; /* XXX: warning here. */
+
+                CHECK_ERROR(net, AddPortForwardRule(
+                              (BOOL)(*it).fPfrIPv6,
+                              Bstr((*it).aszPfrName).raw(),
+                              proto,
+                              Bstr((*it).aszPfrHostAddr).raw(),
+                              (*it).u16PfrHostPort,
+                              Bstr((*it).aszPfrGuestAddr).raw(),
+                              (*it).u16PfrGuestPort));
+                if(FAILED(rc))
+                    return errorArgument("Failed to add pf");
+
+            }
         }
         
