diff --git a/libportfwd/CMakeLists.txt b/libportfwd/CMakeLists.txt
index 9519e1399..88ccaf107 100644
--- a/libportfwd/CMakeLists.txt
+++ b/libportfwd/CMakeLists.txt
@@ -3,8 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 #SET(CMAKE_INSTALL_PREFIX ".")
 
-SET(MINIUPNP_DIR    "third-party/miniupnpc-20090605/")
-SET(NATPMP_DIR      "third-party/libnatpmp")
+SET(MINIUPNP_DIR    "third-party/miniupnpc-1.4.20100609/")
+SET(NATPMP_DIR      "third-party/libnatpmp-20100202")
 
 SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
 SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -20,6 +20,7 @@ INCLUDE_DIRECTORIES(${MINIUPNP_DIR} include)
 ADD_LIBRARY(portfwd STATIC
 
         # the needed bits of miniupnpc (no python module, no tests, no cli)
+        ${MINIUPNP_DIR}/connecthostport.c
         ${MINIUPNP_DIR}/igd_desc_parse.c
         ${MINIUPNP_DIR}/minisoap.c
         ${MINIUPNP_DIR}/minissdpc.c
diff --git a/libportfwd/src/portfwd.cpp b/libportfwd/src/portfwd.cpp
index c74b156d1..e64024621 100644
--- a/libportfwd/src/portfwd.cpp
+++ b/libportfwd/src/portfwd.cpp
@@ -6,6 +6,7 @@
 
 #ifdef WIN32
 #include <winsock2.h>
+#include "../include/portfwd/portfwd.h"
 #endif
 
 Portfwd::Portfwd()
@@ -82,12 +83,12 @@ Portfwd::get_status()
 {
     // get connection speed
     UPNP_GetLinkLayerMaxBitRates(
-        urls->controlURL_CIF, data->servicetype_CIF, &m_downbps, &m_upbps);
+        urls->controlURL_CIF, data->CIF.servicetype, &m_downbps, &m_upbps);
 
     // get external IP adress
     char ip[16];
     if( 0 != UPNP_GetExternalIPAddress( urls->controlURL, 
-                                        data->servicetype, 
+                                        data->CIF.servicetype, 
                                         (char*)&ip ) )
     {
         m_externalip = ""; //failed
@@ -110,7 +111,7 @@ Portfwd::add( unsigned short port, unsigned short internal_port )
    sprintf(port_str, "%d", port);
    sprintf(port_str_internal, "%d", internal_port);
 
-   r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
+   r = UPNP_AddPortMapping(urls->controlURL, data->CIF.servicetype,
                            port_str, port_str_internal, m_lanip.c_str(), "tomahawk", "TCP", NULL);
    if(r!=0)
    {
@@ -131,7 +132,7 @@ Portfwd::remove( unsigned short port )
        return false;
    }
    sprintf(port_str, "%d", port);
-   int r = UPNP_DeletePortMapping(urls->controlURL, data->servicetype, port_str, "TCP", NULL);
+   int r = UPNP_DeletePortMapping(urls->controlURL, data->CIF.servicetype, port_str, "TCP", NULL);
    return r == 0;
 }
 
diff --git a/libportfwd/third-party/libnatpmp-20100202/Changelog.txt b/libportfwd/third-party/libnatpmp-20100202/Changelog.txt
new file mode 100644
index 000000000..9359f72b7
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/Changelog.txt
@@ -0,0 +1,61 @@
+$Id: Changelog.txt,v 1.21 2010/02/02 18:24:43 nanard Exp $
+
+2010/02/02:
+  Fixed compilation under Mac OS X
+
+2009/12/19:
+  improve and fix building under Windows.
+  Project files for MS Visual Studio 2008
+  More simple (and working) code for Win32.
+  More checks in the /proc/net/route parsing. Add some comments.
+
+2009/08/04:
+  improving getgateway.c for windows
+
+2009/07/13:
+  Adding Haiku code in getgateway.c
+
+2009/06/04:
+  Adding Python module thanks to David Wu
+
+2009/03/10:
+  Trying to have windows get gateway working if not using DHCP
+
+2009/02/27:
+  dont include declspec.h if not under WIN32.
+
+2009/01/23:
+  Prefixed the libraries name with lib
+
+2008/10/06:
+  Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE)
+
+2008/07/03:
+  Adding WIN32 code from Robbie Hanson
+
+2008/06/30:
+  added a Solaris implementation for getgateway().
+  added a LICENCE file to the distribution
+
+2008/05/29:
+  Anonymous unions are forbidden in ANSI C. That was causing problems with
+  non-GCC compilers.
+
+2008/04/28:
+  introduced strnatpmperr()
+  improved natpmpc.c sample
+  make install now install the binary
+
+2007/12/13:
+  Fixed getgateway.c for working under OS X ;)
+  Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP
+
+2007/12/11:
+  Fixed getgateway.c for compilation under Mac OS X
+
+2007/12/01:
+  added some comments in .h
+
+2007/11/30:
+  implemented almost everything
+
diff --git a/libportfwd/third-party/miniupnpc-20090605/LICENCE b/libportfwd/third-party/libnatpmp-20100202/LICENSE
similarity index 97%
rename from libportfwd/third-party/miniupnpc-20090605/LICENCE
rename to libportfwd/third-party/libnatpmp-20100202/LICENSE
index a8cfb5ef3..14db2feb9 100644
--- a/libportfwd/third-party/miniupnpc-20090605/LICENCE
+++ b/libportfwd/third-party/libnatpmp-20100202/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2005-2008, Thomas BERNARD 
+Copyright (c) 2007-2009, Thomas BERNARD 
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/libportfwd/third-party/libnatpmp-20100202/README b/libportfwd/third-party/libnatpmp-20100202/README
new file mode 100644
index 000000000..269392d2a
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/README
@@ -0,0 +1,7 @@
+libnatpmp (c) 2007-2009 Thomas Bernard
+contact : miniupnp@free.fr
+
+see http://miniupnp.free.fr/libnatpmp.html
+or http://miniupnp.tuxfamily.org/libnatpmp.html
+for some documentation and code samples.
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/build.bat b/libportfwd/third-party/libnatpmp-20100202/build.bat
new file mode 100644
index 000000000..2d2f27cd7
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/build.bat
@@ -0,0 +1,30 @@
+@echo Compiling with MinGW
+@SET LIBS=-lws2_32 -liphlpapi
+
+@echo Compile getgateway
+gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c
+gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR testgetgateway.c
+gcc -o testgetgateway getgateway.o testgetgateway.o %LIBS%
+del testgetgateway.o
+
+@echo Compile natpmp-static:
+gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c
+gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmp.c
+gcc -c -Wall -Os -DWIN32 wingettimeofday.c
+ar cr natpmp.a getgateway.o natpmp.o wingettimeofday.o
+del getgateway.o natpmp.o
+gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmpc.c
+gcc -o natpmpc-static natpmpc.o natpmp.a %LIBS%
+upx --best natpmpc-static.exe
+del natpmpc.o
+
+@echo Create natpmp.dll:
+gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS getgateway.c
+gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmp.c
+dllwrap -k --driver-name gcc --def natpmp.def --output-def natpmp.dll.def --implib natpmp.lib -o natpmp.dll getgateway.o natpmp.o wingettimeofday.o %LIBS%
+
+@echo Compile natpmp-shared:
+gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmpc.c
+gcc -o natpmpc-shared natpmpc.o natpmp.lib -lws2_32
+upx --best natpmpc-shared.exe
+del *.o
diff --git a/libportfwd/third-party/libnatpmp/declspec.h b/libportfwd/third-party/libnatpmp-20100202/declspec.h
similarity index 100%
rename from libportfwd/third-party/libnatpmp/declspec.h
rename to libportfwd/third-party/libnatpmp-20100202/declspec.h
diff --git a/libportfwd/third-party/libnatpmp/getgateway.c b/libportfwd/third-party/libnatpmp-20100202/getgateway.c
similarity index 69%
rename from libportfwd/third-party/libnatpmp/getgateway.c
rename to libportfwd/third-party/libnatpmp-20100202/getgateway.c
index 3c84de3a6..bcde3ad33 100644
--- a/libportfwd/third-party/libnatpmp/getgateway.c
+++ b/libportfwd/third-party/libnatpmp-20100202/getgateway.c
@@ -1,6 +1,6 @@
-/* $Id: getgateway.c,v 1.13 2009/03/10 10:15:31 nanard Exp $ */
+/* $Id: getgateway.c,v 1.19 2009/12/19 15:20:45 nanard Exp $ */
 /* libnatpmp
- * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+ * Copyright (c) 2007-2009, Thomas BERNARD <miniupnp@free.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -18,13 +18,17 @@
 #ifndef WIN32
 #include <netinet/in.h>
 #endif
+#if !defined(_MSC_VER)
 #include <sys/param.h>
+#endif
 /* There is no portable method to get the default route gateway.
- * So below are three differents functions implementing this.
+ * So below are four (or five ?) differents functions implementing this.
  * Parsing /proc/net/route is for linux.
  * sysctl is the way to access such informations on BSD systems.
  * Many systems should provide route information through raw PF_ROUTE
- * sockets. */
+ * sockets.
+ * In MS Windows, default gateway is found by looking into the registry
+ * or by using GetBestRoute(). */
 #ifdef __linux__
 #define USE_PROC_NET_ROUTE
 #undef USE_SOCKET_ROUTE
@@ -53,9 +57,29 @@
 #undef USE_PROC_NET_ROUTE
 #undef USE_SOCKET_ROUTE
 #undef USE_SYSCTL_NET_ROUTE
-#define USE_WIN32_CODE
+//#define USE_WIN32_CODE
+#define USE_WIN32_CODE_2
 #endif
 
+#ifdef __CYGWIN__
+#undef USE_PROC_NET_ROUTE
+#undef USE_SOCKET_ROUTE
+#undef USE_SYSCTL_NET_ROUTE
+#define USE_WIN32_CODE
+#include <stdarg.h>
+#include <w32api/windef.h>
+#include <w32api/winbase.h>
+#include <w32api/winreg.h>
+#endif 
+
+#ifdef __HAIKU__
+#include <stdlib.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/sockio.h>
+#define USE_HAIKU_CODE
+#endif 
+
 #ifdef USE_SYSCTL_NET_ROUTE
 #include <stdlib.h>
 #include <sys/sysctl.h>
@@ -69,12 +93,19 @@
 #include <net/if.h>
 #include <net/route.h>
 #endif
-#ifdef WIN32
+
+#ifdef USE_WIN32_CODE
 #include <unknwn.h>
 #include <winreg.h>
 #define MAX_KEY_LENGTH 255
 #define MAX_VALUE_LENGTH 16383
 #endif
+
+#ifdef USE_WIN32_CODE_2
+#include <windows.h>
+#include <iphlpapi.h>
+#endif
+
 #include "getgateway.h"
 
 #ifndef WIN32
@@ -83,9 +114,20 @@
 #endif
 
 #ifdef USE_PROC_NET_ROUTE
+/*
+ parse /proc/net/route which is as follow :
+
+Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT           
+wlan0   0001A8C0        00000000        0001    0       0       0       00FFFFFF        0       0       0              
+eth0    0000FEA9        00000000        0001    0       0       0       0000FFFF        0       0       0              
+wlan0   00000000        0101A8C0        0003    0       0       0       00000000        0       0       0              
+eth0    00000000        00000000        0001    0       0       1000    00000000        0       0       0              
+
+ One header line, and then one line by route by route table entry.
+*/
 int getdefaultgateway(in_addr_t * addr)
 {
-	long d, g;
+	unsigned long d, g;
 	char buf[256];
 	int line = 0;
 	FILE * f;
@@ -94,14 +136,15 @@ int getdefaultgateway(in_addr_t * addr)
 	if(!f)
 		return FAILED;
 	while(fgets(buf, sizeof(buf), f)) {
-		if(line > 0) {
+		if(line > 0) {	/* skip the first line */
 			p = buf;
+			/* skip the interface name */
 			while(*p && !isspace(*p))
 				p++;
 			while(*p && isspace(*p))
 				p++;
 			if(sscanf(p, "%lx%lx", &d, &g)==2) {
-				if(d == 0) { /* default */
+				if(d == 0 && g != 0) { /* default */
 					*addr = g;
 					fclose(f);
 					return SUCCESS;
@@ -261,7 +304,7 @@ int getdefaultgateway(in_addr_t *addr)
 #endif /* #ifdef USE_SOCKET_ROUTE */
 
 #ifdef USE_WIN32_CODE
-int getdefaultgateway(in_addr_t * addr)
+LIBSPEC int getdefaultgateway(in_addr_t * addr)
 {
 	HKEY networkCardsKey;
 	HKEY networkCardKey;
@@ -279,9 +322,21 @@ int getdefaultgateway(in_addr_t * addr)
 	DWORD gatewayValueType = REG_MULTI_SZ;
 	int done = 0;
 	
-	char networkCardsPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-	char interfacesPath[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-	
+	//const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
+	//const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
+#ifdef UNICODE
+	LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
+	LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
+#define STR_SERVICENAME	 L"ServiceName"
+#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway"
+#define STR_DEFAULTGATEWAY	L"DefaultGateway"
+#else
+	LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
+	LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
+#define STR_SERVICENAME	 "ServiceName"
+#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway"
+#define STR_DEFAULTGATEWAY	"DefaultGateway"
+#endif
 	// The windows registry lists its primary network devices in the following location:
 	// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
 	// 
@@ -361,40 +416,39 @@ int getdefaultgateway(in_addr_t * addr)
 			{
 				keyValueLength = MAX_VALUE_LENGTH;
 				if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey,   // Open registry key
-				                                    "ServiceName",    // Name of key to query
+				                                    STR_SERVICENAME,    // Name of key to query
 				                                    NULL,             // Reserved - must be NULL
 				                                    &keyValueType,    // Receives value type
-				                                    keyValue,         // Receives value
+				                                    (LPBYTE)keyValue, // Receives value
 				                                    &keyValueLength)) // Receives value length in bytes
 				{
-					//printf("keyValue: %s\n", keyValue);
-					
+//					printf("keyValue: %s\n", keyValue);				
 					if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS)
 					{
 						gatewayValueLength = MAX_VALUE_LENGTH;
 						if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey,         // Open registry key
-						                                    "DhcpDefaultGateway", // Name of key to query
+						                                    STR_DHCPDEFAULTGATEWAY, // Name of key to query
 						                                    NULL,                 // Reserved - must be NULL
 						                                    &gatewayValueType,    // Receives value type
-						                                    gatewayValue,         // Receives value
+						                                    (LPBYTE)gatewayValue, // Receives value
 						                                    &gatewayValueLength)) // Receives value length in bytes
 						{
 							// Check to make sure it's a string
-							if(gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ)
+							if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
 							{
 								//printf("gatewayValue: %s\n", gatewayValue);
 								done = 1;
 							}
 						}
 						else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey,         // Open registry key
-						                                    "DefaultGateway", // Name of key to query
+						                                    STR_DEFAULTGATEWAY, // Name of key to query
 						                                    NULL,                 // Reserved - must be NULL
 						                                    &gatewayValueType,    // Receives value type
-						                                    gatewayValue,         // Receives value
+						                                    (LPBYTE)gatewayValue,// Receives value
 						                                    &gatewayValueLength)) // Receives value length in bytes
 						{
 							// Check to make sure it's a string
-							if(gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ)
+							if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
 							{
 								//printf("gatewayValue: %s\n", gatewayValue);
 								done = 1;
@@ -413,7 +467,18 @@ int getdefaultgateway(in_addr_t * addr)
 	
 	if(done)
 	{
+#if UNICODE
+		char tmp[32];
+		for(i = 0; i < 32; i++) {
+			tmp[i] = (char)gatewayValue[i];
+			if(!tmp[i])
+				break;
+		}
+		tmp[31] = '\0';
+		*addr = inet_addr(tmp);
+#else
 		*addr = inet_addr(gatewayValue);
+#endif
 		return 0;
 	}
 	
@@ -421,3 +486,69 @@ int getdefaultgateway(in_addr_t * addr)
 }
 #endif /* #ifdef USE_WIN32_CODE */
 
+#ifdef USE_WIN32_CODE_2
+int getdefaultgateway(in_addr_t *addr)
+{
+	MIB_IPFORWARDROW ip_forward;
+	memset(&ip_forward, 0, sizeof(ip_forward));
+	if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR)
+		return -1;
+	*addr = ip_forward.dwForwardNextHop;
+	return 0;
+}
+#endif /* #ifdef USE_WIN32_CODE_2 */
+
+#ifdef USE_HAIKU_CODE
+int getdefaultgateway(in_addr_t *addr)
+{
+    int fd, ret = -1;
+    struct ifconf config;
+    void *buffer = NULL;
+    struct ifreq *interface;
+
+    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        return -1;
+    }
+    if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) {
+        goto fail;
+    }
+    if (config.ifc_value < 1) {
+        goto fail; /* No routes */
+    }
+    if ((buffer = malloc(config.ifc_value)) == NULL) {
+        goto fail;
+    }
+    config.ifc_len = config.ifc_value;
+    config.ifc_buf = buffer;
+    if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) {
+        goto fail;
+    }
+    for (interface = buffer;
+      (uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) {
+        struct route_entry route = interface->ifr_route;
+        int intfSize;
+        if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) {
+            *addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr;
+            ret = 0;
+            break;
+        }
+        intfSize = sizeof(route) + IF_NAMESIZE;
+        if (route.destination != NULL) {
+            intfSize += route.destination->sa_len;
+        }
+        if (route.mask != NULL) {
+            intfSize += route.mask->sa_len;
+        }
+        if (route.gateway != NULL) {
+            intfSize += route.gateway->sa_len;
+        }
+        interface = (struct ifreq *)((uint8_t *)interface + intfSize);
+    }
+fail:
+    free(buffer);
+    close(fd);
+    return ret;
+}
+#endif /* #ifdef USE_HAIKU_CODE */
+
+
diff --git a/libportfwd/third-party/libnatpmp/getgateway.h b/libportfwd/third-party/libnatpmp-20100202/getgateway.h
similarity index 86%
rename from libportfwd/third-party/libnatpmp/getgateway.h
rename to libportfwd/third-party/libnatpmp-20100202/getgateway.h
index cf7794600..9432528b8 100644
--- a/libportfwd/third-party/libnatpmp/getgateway.h
+++ b/libportfwd/third-party/libnatpmp-20100202/getgateway.h
@@ -1,4 +1,4 @@
-/* $Id: getgateway.h,v 1.3 2008/07/02 22:33:06 nanard Exp $ */
+/* $Id: getgateway.h,v 1.4 2009/12/19 12:00:00 nanard Exp $ */
 /* libnatpmp
  * Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
  *
@@ -17,7 +17,12 @@
 #define __GETGATEWAY_H__
 
 #ifdef WIN32
+#if !defined(_MSC_VER)
 #include <stdint.h>
+#else
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+#endif
 #define in_addr_t uint32_t
 #endif
 #include "declspec.h"
diff --git a/libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c b/libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c
new file mode 100644
index 000000000..b08384e0a
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/libnatpmpmodule.c
@@ -0,0 +1,268 @@
+/* $Id: libnatpmpmodule.c,v 1.3 2009/12/19 12:00:00 nanard Exp $ */
+/* libnatpmp
+ * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+ * http://miniupnp.free.fr/libnatpmp.html
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <Python.h>
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#define STATICLIB
+#include "structmember.h"
+#include "natpmp.h"
+
+/* for compatibility with Python < 2.4 */
+#ifndef Py_RETURN_NONE
+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+#endif
+
+#ifndef Py_RETURN_TRUE
+#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
+#endif
+
+#ifndef Py_RETURN_FALSE
+#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
+#endif
+
+typedef struct {
+  PyObject_HEAD
+
+  /* Type-specific fields go here. */
+  unsigned int discoverdelay;
+  
+  natpmp_t natpmp;
+} NATPMPObject;
+
+static PyMemberDef NATPMP_members[] = {
+  {"discoverdelay", T_UINT, offsetof(NATPMPObject, discoverdelay),
+   0/*READWRITE*/, "value in ms used to wait for NATPMP responses"
+  },
+  {NULL}
+};
+
+static PyObject *
+NATPMPObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+  NATPMPObject *self;
+  
+  self = (NATPMPObject *)type->tp_alloc(type, 0);
+  if (self) {
+    initnatpmp(&self->natpmp);
+  }
+
+  return (PyObject *)self;
+}
+
+static void
+NATPMPObject_dealloc(NATPMPObject *self)
+{
+  closenatpmp(&self->natpmp);
+  self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+NATPMP_externalipaddress(NATPMPObject *self)
+{
+  int r;
+  struct timeval timeout;
+  fd_set fds;
+  natpmpresp_t response;
+  
+  r = sendpublicaddressrequest(&self->natpmp);
+  
+  if (r < 0) {
+#ifdef ENABLE_STRNATPMPERR
+    PyErr_SetString(PyExc_Exception, strnatpmperr(r));
+#endif
+    return NULL;
+  }
+    
+  do {
+    FD_ZERO(&fds);
+    FD_SET(self->natpmp.s, &fds);
+    getnatpmprequesttimeout(&self->natpmp, &timeout);
+    select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+    r = readnatpmpresponseorretry(&self->natpmp, &response);
+    if (r < 0 && r != NATPMP_TRYAGAIN) {
+#ifdef ENABLE_STRNATPMPERR
+      PyErr_SetString(PyExc_Exception, strnatpmperr(r));
+#endif
+      return NULL;
+    }
+  } while (r == NATPMP_TRYAGAIN);
+
+  return Py_BuildValue("s", inet_ntoa(response.pnu.publicaddress.addr));
+}
+
+static PyObject *
+NATPMP_domapping(natpmp_t *n, unsigned short eport, unsigned short iport, 
+		 const char *protocol, unsigned int lifetime)
+{
+  int proto;
+  struct timeval timeout;
+  fd_set fds;
+  natpmpresp_t response;
+  int r;
+
+  if (!strncasecmp("tcp", protocol, 3)) {
+    proto = NATPMP_PROTOCOL_TCP;
+  } else if (!strncasecmp("udp", protocol, 3)) {
+    proto = NATPMP_PROTOCOL_UDP;
+  } else {
+    PyErr_SetString(PyExc_Exception, "Unknown protocol");
+    return NULL;
+  }
+
+  r = sendnewportmappingrequest(n, proto, iport, eport, 
+				lifetime);
+
+  if (r < 0) {
+#ifdef ENABLE_STRNATPMPERR
+    PyErr_SetString(PyExc_Exception, strnatpmperr(r));
+#endif
+    return NULL;
+  }
+  
+  do {
+    FD_ZERO(&fds);
+    FD_SET(n->s, &fds);
+    getnatpmprequesttimeout(n, &timeout);
+    select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+    r = readnatpmpresponseorretry(n, &response);
+    if (r < 0 && r != NATPMP_TRYAGAIN) {
+#ifdef ENABLE_STRNATPMPERR
+      PyErr_SetString(PyExc_Exception, strnatpmperr(r));
+#endif
+      return NULL;
+    }
+  } while (r == NATPMP_TRYAGAIN);
+
+  return Py_BuildValue("H", response.pnu.newportmapping.mappedpublicport);
+}
+
+
+/* AddPortMapping(externalPort, protocol, internalPort, lifetime)
+ * protocol is 'UDP' or 'TCP' */
+static PyObject *
+NATPMP_addportmapping(NATPMPObject *self, PyObject *args)
+{
+  unsigned short eport;
+  unsigned short iport;
+  unsigned int lifetime;
+  const char *protocol;
+
+  if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport, &lifetime))
+    return NULL;
+  
+  return NATPMP_domapping(&self->natpmp, eport, iport, protocol, lifetime);
+}
+
+/* DeletePortMapping(externalPort, protocol, internalPort)
+ * protocol is 'UDP' or 'TCP' */
+static PyObject *
+NATPMP_deleteportmapping(NATPMPObject *self, PyObject *args)
+{
+  unsigned short eport;
+  unsigned short iport;
+  const char *protocol;
+
+  if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport))
+    return NULL;
+  
+  return NATPMP_domapping(&self->natpmp, eport, iport, protocol, 0);
+}
+
+/* natpmp.NATPMP object Method Table */
+static PyMethodDef NATPMP_methods[] = {
+  {"externalipaddress", (PyCFunction)NATPMP_externalipaddress, METH_NOARGS,
+   "return external IP address"
+  },
+  {"addportmapping", (PyCFunction)NATPMP_addportmapping, METH_VARARGS,
+   "add a port mapping"
+  },
+  {"deleteportmapping", (PyCFunction)NATPMP_deleteportmapping, METH_VARARGS,
+   "delete a port mapping"
+  },
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject NATPMPType = {
+  PyObject_HEAD_INIT(NULL)
+  0,					/*ob_size*/
+  "libnatpmp.NATPMP",			/*tp_name*/
+  sizeof(NATPMPObject),			/*tp_basicsize*/
+  0,					/*tp_itemsize*/
+  (destructor)NATPMPObject_dealloc,	/*tp_dealloc*/
+  0,					/*tp_print*/
+  0,					/*tp_getattr*/
+  0,					/*tp_setattr*/
+  0,					/*tp_compare*/
+  0,					/*tp_repr*/
+  0,					/*tp_as_number*/
+  0,					/*tp_as_sequence*/
+  0,					/*tp_as_mapping*/
+  0,					/*tp_hash */
+  0,					/*tp_call*/
+  0,					/*tp_str*/
+  0,					/*tp_getattro*/
+  0,					/*tp_setattro*/
+  0,					/*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,			/*tp_flags*/
+  "NATPMP objects",			/* tp_doc */
+  0,					/* tp_traverse */
+  0,					/* tp_clear */
+  0,					/* tp_richcompare */
+  0,					/* tp_weaklistoffset */
+  0,					/* tp_iter */
+  0,					/* tp_iternext */
+  NATPMP_methods,			/* tp_methods */
+  NATPMP_members,			/* tp_members */
+  0,					/* tp_getset */
+  0,					/* tp_base */
+  0,					/* tp_dict */
+  0,					/* tp_descr_get */
+  0,					/* tp_descr_set */
+  0,					/* tp_dictoffset */
+  0,					/* tp_init */
+  0,					/* tp_alloc */
+  NATPMPObject_new,			/* tp_new */
+};
+
+/* module methods */
+static PyMethodDef libnatpmp_methods[] = {
+    {NULL}  /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initlibnatpmp(void) 
+{
+  PyObject* m;
+  
+  if (PyType_Ready(&NATPMPType) < 0)
+    return;
+  
+  m = Py_InitModule3("libnatpmp", libnatpmp_methods,
+		     "libnatpmp module.");
+
+  Py_INCREF(&NATPMPType);
+  PyModule_AddObject(m, "NATPMP", (PyObject *)&NATPMPType);
+}
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln
new file mode 100644
index 000000000..ac746d415
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.sln
@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnatpmp", "libnatpmp.vcproj", "{D59B6527-F3DE-4D26-A08D-52F1EE989301}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "natpmpc-static", "natpmpc-static.vcproj", "{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{D59B6527-F3DE-4D26-A08D-52F1EE989301} = {D59B6527-F3DE-4D26-A08D-52F1EE989301}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.Build.0 = Debug|Win32
+		{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.ActiveCfg = Release|Win32
+		{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.Build.0 = Release|Win32
+		{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.Build.0 = Debug|Win32
+		{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.ActiveCfg = Release|Win32
+		{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj
new file mode 100644
index 000000000..9bae5c185
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/msvc/libnatpmp.vcproj
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="libnatpmp"
+	ProjectGUID="{D59B6527-F3DE-4D26-A08D-52F1EE989301}"
+	RootNamespace="libnatpmp"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;STATICLIB"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;STATICLIB"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Fichiers sources"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\getgateway.c"
+				>
+			</File>
+			<File
+				RelativePath="..\natpmp.c"
+				>
+			</File>
+			<File
+				RelativePath="..\wingettimeofday.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Fichiers d&apos;en-t�te"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\declspec.h"
+				>
+			</File>
+			<File
+				RelativePath="..\getgateway.h"
+				>
+			</File>
+			<File
+				RelativePath="..\natpmp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\wingettimeofday.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Fichiers de ressources"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj b/libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj
new file mode 100644
index 000000000..c2052d982
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/msvc/natpmpc-static.vcproj
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="natpmpc-static"
+	ProjectGUID="{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}"
+	RootNamespace="natpmpcstatic"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;STATICLIB;_CRT_SECURE_NO_WARNINGS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib Iphlpapi.lib"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;STATICLIB;_CRT_SECURE_NO_WARNINGS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Fichiers sources"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\natpmpc.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Fichiers d&apos;en-t�te"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Fichiers de ressources"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/libportfwd/third-party/libnatpmp/natpmp.c b/libportfwd/third-party/libnatpmp-20100202/natpmp.c
similarity index 92%
rename from libportfwd/third-party/libnatpmp/natpmp.c
rename to libportfwd/third-party/libnatpmp-20100202/natpmp.c
index f1c95b1ad..055ba4f0a 100644
--- a/libportfwd/third-party/libnatpmp/natpmp.c
+++ b/libportfwd/third-party/libnatpmp-20100202/natpmp.c
@@ -1,6 +1,6 @@
-/* $Id: natpmp.c,v 1.8 2008/07/02 22:33:06 nanard Exp $ */
+/* $Id: natpmp.c,v 1.12 2009/12/19 14:10:09 nanard Exp $ */
 /* libnatpmp
- * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+ * Copyright (c) 2007-2009, Thomas BERNARD <miniupnp@free.fr>
  * http://miniupnp.free.fr/libnatpmp.html
  *
  * Permission to use, copy, modify, and/or distribute this software for any
@@ -14,15 +14,22 @@
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#ifdef __linux__
+#define _BSD_SOURCE 1
+#endif
 #include <string.h>
 #include <time.h>
+#if !defined(_MSC_VER)
 #include <sys/time.h>
+#endif
 #ifdef WIN32
+#include <errno.h>
 #include <winsock2.h>
-#include <Ws2tcpip.h>
+#include <ws2tcpip.h>
 #include <io.h>
 #define EWOULDBLOCK WSAEWOULDBLOCK
 #define ECONNREFUSED WSAECONNREFUSED
+#include "wingettimeofday.h"
 #else
 #include <errno.h>
 #include <unistd.h>
@@ -34,7 +41,7 @@
 #include "natpmp.h"
 #include "getgateway.h"
 
-int initnatpmp(natpmp_t * p)
+LIBSPEC int initnatpmp(natpmp_t * p)
 {
 #ifdef WIN32
 	u_long ioctlArg = 1;
@@ -70,7 +77,7 @@ int initnatpmp(natpmp_t * p)
 	return 0;
 }
 
-int closenatpmp(natpmp_t * p)
+LIBSPEC int closenatpmp(natpmp_t * p)
 {
 	if(!p)
 		return NATPMP_ERR_INVALIDARGS;
@@ -79,7 +86,7 @@ int closenatpmp(natpmp_t * p)
 	return 0;
 }
 
-static int sendpendingrequest(natpmp_t * p)
+int sendpendingrequest(natpmp_t * p)
 {
 	int r;
 /*	struct sockaddr_in addr;*/
@@ -95,7 +102,7 @@ static int sendpendingrequest(natpmp_t * p)
 	return (r<0) ? NATPMP_ERR_SENDERR : r;
 }
 
-static int sendnatpmprequest(natpmp_t * p)
+int sendnatpmprequest(natpmp_t * p)
 {
 	int n;
 	if(!p)
@@ -113,7 +120,7 @@ static int sendnatpmprequest(natpmp_t * p)
 	return n;
 }
 
-int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
+LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
 {
 	struct timeval now;
 	if(!p || !timeout)
@@ -131,7 +138,7 @@ int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
 	return 0;
 }
 
-int sendpublicaddressrequest(natpmp_t * p)
+LIBSPEC int sendpublicaddressrequest(natpmp_t * p)
 {
 	if(!p)
 		return NATPMP_ERR_INVALIDARGS;
@@ -143,7 +150,7 @@ int sendpublicaddressrequest(natpmp_t * p)
 	return sendnatpmprequest(p);
 }
 
-int sendnewportmappingrequest(natpmp_t * p, int protocol,
+LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
                               uint16_t privateport, uint16_t publicport,
 							  uint32_t lifetime)
 {
@@ -160,7 +167,7 @@ int sendnewportmappingrequest(natpmp_t * p, int protocol,
 	return sendnatpmprequest(p);
 }
 
-static int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response)
+LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response)
 {
 	unsigned char buf[16];
 	struct sockaddr_in addr;
@@ -268,7 +275,7 @@ int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response)
 }
 
 #ifdef ENABLE_STRNATPMPERR
-const char * strnatpmperr(int r)
+LIBSPEC const char * strnatpmperr(int r)
 {
 	const char * s;
 	switch(r) {
diff --git a/libportfwd/third-party/libnatpmp-20100202/natpmp.def b/libportfwd/third-party/libnatpmp-20100202/natpmp.def
new file mode 100644
index 000000000..cd110033f
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/natpmp.def
@@ -0,0 +1,11 @@
+LIBRARY
+; libnatpmp library
+
+EXPORTS
+  initnatpmp
+  closenatpmp
+  sendpublicaddressrequest
+  sendnewportmappingrequest
+  getnatpmprequesttimeout
+  readnatpmpresponseorretry
+  strnatpmperr
diff --git a/libportfwd/third-party/libnatpmp/natpmp.h b/libportfwd/third-party/libnatpmp-20100202/natpmp.h
similarity index 96%
rename from libportfwd/third-party/libnatpmp/natpmp.h
rename to libportfwd/third-party/libnatpmp-20100202/natpmp.h
index d1f09c26a..d4c513ee5 100644
--- a/libportfwd/third-party/libnatpmp/natpmp.h
+++ b/libportfwd/third-party/libnatpmp-20100202/natpmp.h
@@ -1,4 +1,4 @@
-/* $Id: natpmp.h,v 1.11 2009/02/27 22:38:05 nanard Exp $ */
+/* $Id: natpmp.h,v 1.12 2009/12/19 12:00:00 nanard Exp $ */
 /* libnatpmp
  * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
  * http://miniupnp.free.fr/libnatpmp.html
@@ -21,10 +21,17 @@
 #define NATPMP_PORT (5351)
 
 #include <time.h>
+#if !defined(_MSC_VER)
 #include <sys/time.h>
+#endif
 #ifdef WIN32
 #include <winsock2.h>
+#if !defined(_MSC_VER)
 #include <stdint.h>
+#else
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+#endif
 #define in_addr_t uint32_t
 #include "declspec.h"
 #else
diff --git a/libportfwd/third-party/libnatpmp-20100202/natpmpc.c b/libportfwd/third-party/libnatpmp-20100202/natpmpc.c
new file mode 100644
index 000000000..3cc852baa
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/natpmpc.c
@@ -0,0 +1,210 @@
+/* $Id: natpmpc.c,v 1.7 2009/12/19 12:00:00 nanard Exp $ */
+/* libnatpmp
+ * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+ * http://miniupnp.free.fr/libnatpmp.html
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#if defined(_MSC_VER)
+#if _MSC_VER >= 1400
+#define strcasecmp _stricmp
+#else
+#define strcasecmp stricmp
+#endif
+#else
+#include <unistd.h>
+#endif
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include "natpmp.h"
+
+void usage(FILE * out, const char * argv0)
+{
+	fprintf(out, "Usage :\n");
+	fprintf(out, "  %s\n", argv0);
+	fprintf(out, "\tdisplay the public IP address.\n");
+	fprintf(out, "  %s -h\n", argv0);
+	fprintf(out, "\tdisplay this help screen.\n");
+	fprintf(out, "  %s -a <public port> <private port> <protocol> [lifetime]\n", argv0);
+	fprintf(out, "\tadd a port mapping.\n");
+	fprintf(out, "\n  In order to remove a mapping, set it with a lifetime of 0 seconds.\n");
+	fprintf(out, "  To remove all mappings for your machine, use 0 as private port and lifetime.\n");
+}
+
+/* sample code for using libnatpmp */
+int main(int argc, char * * argv)
+{
+	natpmp_t natpmp;
+	natpmpresp_t response;
+	int r;
+	int sav_errno;
+	struct timeval timeout;
+	fd_set fds;
+	int i;
+	int protocol = 0;
+	uint16_t privateport = 0;
+	uint16_t publicport = 0;
+	uint32_t lifetime = 3600;
+	int command = 0;
+
+#ifdef WIN32
+	WSADATA wsaData;
+	int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+	if(nResult != NO_ERROR)
+	{
+		fprintf(stderr, "WSAStartup() failed.\n");
+		return -1;
+	}
+#endif
+
+	/* argument parsing */
+	for(i=1; i<argc; i++) {
+		if(argv[i][0] == '-') {
+			switch(argv[i][1]) {
+			case 'h':
+				usage(stdout, argv[0]);
+				return 0;
+			case 'a':
+				command = 'a';
+				if(argc < i + 3) {
+					fprintf(stderr, "Not enough arguments for option -a\n");
+					return 1;
+				}
+				i++;
+				if(1 != sscanf(argv[i], "%hu", &publicport)) {
+					fprintf(stderr, "%s is not a correct 16bits unsigned integer\n", argv[i]);
+					return 1;
+				}
+				i++;
+				if(1 != sscanf(argv[i], "%hu", &privateport)) {
+					fprintf(stderr, "%s is not a correct 16bits unsigned integer\n", argv[i]);
+					return 1;
+				}
+				i++;
+				if(0 == strcasecmp(argv[i], "tcp"))
+					protocol = NATPMP_PROTOCOL_TCP;
+				else if(0 == strcasecmp(argv[i], "udp"))
+					protocol = NATPMP_PROTOCOL_UDP;
+				else {
+					fprintf(stderr, "%s is not a valid protocol\n", argv[i]);
+					return 1;
+				}
+				if(argc >= i) {
+					i++;
+					if(1 != sscanf(argv[i], "%u", &lifetime)) {
+						fprintf(stderr, "%s is not a correct 32bits unsigned integer\n", argv[i]);
+					}
+				}
+				break;
+			default:
+				fprintf(stderr, "Unknown option %s\n", argv[i]);
+				usage(stderr, argv[0]);
+				return 1;
+			}
+		} else {
+			fprintf(stderr, "Unknown option %s\n", argv[i]);
+			usage(stderr, argv[0]);
+			return 1;
+		}
+	}
+
+	/* initnatpmp() */
+	r = initnatpmp(&natpmp);
+	printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS");
+	if(r<0)
+		return 1;
+
+	/* sendpublicaddressrequest() */
+	r = sendpublicaddressrequest(&natpmp);
+	printf("sendpublicaddressrequest returned %d (%s)\n",
+	       r, r==2?"SUCCESS":"FAILED");
+	if(r<0)
+		return 1;
+
+	do {
+		FD_ZERO(&fds);
+		FD_SET(natpmp.s, &fds);
+		getnatpmprequesttimeout(&natpmp, &timeout);
+		select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+		r = readnatpmpresponseorretry(&natpmp, &response);
+		sav_errno = errno;
+		printf("readnatpmpresponseorretry returned %d (%s)\n",
+		       r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
+		if(r<0 && r!=NATPMP_TRYAGAIN) {
+#ifdef ENABLE_STRNATPMPERR
+			fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n",
+			        strnatpmperr(r));
+#endif
+			fprintf(stderr, "  errno=%d '%s'\n", 
+			        sav_errno, strerror(sav_errno));
+		}
+	} while(r==NATPMP_TRYAGAIN);
+	if(r<0)
+		return 1;
+
+	/* TODO : check that response.type == 0 */
+	printf("Public IP address : %s\n", inet_ntoa(response.pnu.publicaddress.addr));
+	printf("epoch = %u\n", response.epoch);
+
+	if(command == 'a') {
+		/* sendnewportmappingrequest() */
+		r = sendnewportmappingrequest(&natpmp, protocol,
+        	                      privateport, publicport,
+								  lifetime);
+		printf("sendnewportmappingrequest returned %d (%s)\n",
+		       r, r==12?"SUCCESS":"FAILED");
+		if(r < 0)
+			return 1;
+
+		do {
+			FD_ZERO(&fds);
+			FD_SET(natpmp.s, &fds);
+			getnatpmprequesttimeout(&natpmp, &timeout);
+			select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+			r = readnatpmpresponseorretry(&natpmp, &response);
+			printf("readnatpmpresponseorretry returned %d (%s)\n",
+			       r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
+		} while(r==NATPMP_TRYAGAIN);
+		if(r<0) {
+#ifdef ENABLE_STRNATPMPERR
+			fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n",
+			        strnatpmperr(r));
+#endif
+			return 1;
+		}
+	
+		printf("Mapped public port %hu protocol %s to local port %hu "
+		       "liftime %u\n",
+	    	   response.pnu.newportmapping.mappedpublicport,
+			   response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
+			    (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" :
+			     "UNKNOWN"),
+			   response.pnu.newportmapping.privateport,
+			   response.pnu.newportmapping.lifetime);
+		printf("epoch = %u\n", response.epoch);
+	}
+
+	r = closenatpmp(&natpmp);
+	printf("closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED");
+	if(r<0)
+		return 1;
+
+	return 0;
+}
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/setup.py b/libportfwd/third-party/libnatpmp-20100202/setup.py
new file mode 100644
index 000000000..1386bf216
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/setup.py
@@ -0,0 +1,15 @@
+#! /usr/bin/python
+# $Id: setup.py,v 1.2 2009/06/04 21:37:06 nanard Exp $
+#
+# python script to build the libnatpmp module under unix
+#
+# replace libnatpmp.a by libnatpmp.so for shared library usage
+from distutils.core import setup, Extension
+setup(name="libnatpmp", version="1.0",
+      ext_modules=[
+        Extension(name="libnatpmp", sources=["libnatpmpmodule.c"],
+                  extra_objects=["libnatpmp.a"],
+                  define_macros=[('ENABLE_STRNATPMPERR', None)]
+        )]
+     )
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/setupmingw32.py b/libportfwd/third-party/libnatpmp-20100202/setupmingw32.py
new file mode 100644
index 000000000..87491b6b9
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/setupmingw32.py
@@ -0,0 +1,14 @@
+#! /usr/bin/python
+# $Id: setupmingw32.py,v 1.2 2009/06/04 21:37:06 nanard Exp $
+# python script to build the miniupnpc module under windows
+#
+from distutils.core import setup, Extension
+setup(name="libnatpmp", version="1.0",
+      ext_modules=[
+        Extension(name="libnatpmp", sources=["libnatpmpmodule.c"],
+                  libraries=["ws2_32"],
+                  extra_objects=["libnatpmp.a"],
+                  define_macros=[('ENABLE_STRNATPMPERR', None)]
+        )]
+     )
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/testgetgateway.c b/libportfwd/third-party/libnatpmp-20100202/testgetgateway.c
new file mode 100644
index 000000000..d559683a6
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/testgetgateway.c
@@ -0,0 +1,42 @@
+/* $Id: testgetgateway.c,v 1.4 2008/07/02 22:33:06 nanard Exp $ */
+/* libnatpmp
+ * Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <stdio.h>
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include "getgateway.h"
+
+int main(int argc, char * * argv)
+{
+	struct in_addr gatewayaddr;
+	int r;
+#ifdef WIN32
+	uint32_t temp = 0;
+	r = getdefaultgateway(&temp);
+	gatewayaddr.S_un.S_addr = temp;
+#else
+	r = getdefaultgateway(&(gatewayaddr.s_addr));
+#endif
+	if(r>=0)
+		printf("default gateway : %s\n", inet_ntoa(gatewayaddr));
+	else
+		fprintf(stderr, "getdefaultgateway() failed\n");
+	return 0;
+}
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c
new file mode 100644
index 000000000..5b1b8a63a
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.c
@@ -0,0 +1,50 @@
+/* $Id: wingettimeofday.c,v 1.3 2009/12/19 12:00:00 nanard Exp $ */
+/* libnatpmp
+ * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+ * http://miniupnp.free.fr/libnatpmp.html
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#ifdef WIN32
+#if defined(_MSC_VER)
+struct timeval {
+	long    tv_sec;
+	long    tv_usec;
+};
+#else
+#include <sys/time.h>
+#endif
+
+typedef struct _FILETIME {
+    unsigned long dwLowDateTime;
+    unsigned long dwHighDateTime;
+} FILETIME;
+
+void __stdcall GetSystemTimeAsFileTime(FILETIME*);
+  
+//int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
+
+int gettimeofday(struct timeval* p, void* tz /* IGNORED */) {
+  union {
+   long long ns100; /*time since 1 Jan 1601 in 100ns units */
+   FILETIME ft;
+  } _now;
+
+	if(!p)
+		return -1;
+  GetSystemTimeAsFileTime( &(_now.ft) );
+  p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL );
+  p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL);
+  return 0;
+}
+#endif
+
diff --git a/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h
new file mode 100644
index 000000000..ed6c599ee
--- /dev/null
+++ b/libportfwd/third-party/libnatpmp-20100202/wingettimeofday.h
@@ -0,0 +1,27 @@
+/* $Id: wingettimeofday.h,v 1.1 2009/12/19 12:02:42 nanard Exp $ */
+/* libnatpmp
+ * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
+ * http://miniupnp.free.fr/libnatpmp.html
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#ifndef __WINGETTIMEOFDAY_H__
+#define __WINGETTIMEOFDAY_H__
+#ifdef WIN32
+#if defined(_MSC_VER)
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
+#endif
+#endif
diff --git a/libportfwd/third-party/libnatpmp/.deps/getgateway.Po b/libportfwd/third-party/libnatpmp/.deps/getgateway.Po
deleted file mode 100644
index afb5e4801..000000000
--- a/libportfwd/third-party/libnatpmp/.deps/getgateway.Po
+++ /dev/null
@@ -1,133 +0,0 @@
-getgateway.o: getgateway.c /usr/include/stdio.h /usr/include/features.h \
-  /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
-  /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
-  /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h \
-  /usr/include/bits/types.h /usr/include/bits/typesizes.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
-  /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stdarg.h \
-  /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
-  /usr/include/bits/stdio.h /usr/include/bits/stdio2.h \
-  /usr/include/ctype.h /usr/include/endian.h /usr/include/bits/endian.h \
-  /usr/include/bits/byteswap.h /usr/include/netinet/in.h \
-  /usr/include/stdint.h /usr/include/bits/wchar.h \
-  /usr/include/sys/socket.h /usr/include/sys/uio.h \
-  /usr/include/sys/types.h /usr/include/time.h /usr/include/sys/select.h \
-  /usr/include/bits/select.h /usr/include/bits/sigset.h \
-  /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
-  /usr/include/bits/pthreadtypes.h /usr/include/bits/uio.h \
-  /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \
-  /usr/include/asm/socket.h /usr/include/asm/sockios.h \
-  /usr/include/bits/socket2.h /usr/include/bits/in.h \
-  /usr/include/sys/param.h \
-  /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/limits.h \
-  /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/syslimits.h \
-  /usr/include/limits.h /usr/include/bits/posix1_lim.h \
-  /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
-  /usr/include/bits/posix2_lim.h /usr/include/linux/param.h \
-  /usr/include/asm/param.h getgateway.h declspec.h
-
-/usr/include/stdio.h:
-
-/usr/include/features.h:
-
-/usr/include/sys/cdefs.h:
-
-/usr/include/bits/wordsize.h:
-
-/usr/include/gnu/stubs.h:
-
-/usr/include/gnu/stubs-64.h:
-
-/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h:
-
-/usr/include/bits/types.h:
-
-/usr/include/bits/typesizes.h:
-
-/usr/include/libio.h:
-
-/usr/include/_G_config.h:
-
-/usr/include/wchar.h:
-
-/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stdarg.h:
-
-/usr/include/bits/stdio_lim.h:
-
-/usr/include/bits/sys_errlist.h:
-
-/usr/include/bits/stdio.h:
-
-/usr/include/bits/stdio2.h:
-
-/usr/include/ctype.h:
-
-/usr/include/endian.h:
-
-/usr/include/bits/endian.h:
-
-/usr/include/bits/byteswap.h:
-
-/usr/include/netinet/in.h:
-
-/usr/include/stdint.h:
-
-/usr/include/bits/wchar.h:
-
-/usr/include/sys/socket.h:
-
-/usr/include/sys/uio.h:
-
-/usr/include/sys/types.h:
-
-/usr/include/time.h:
-
-/usr/include/sys/select.h:
-
-/usr/include/bits/select.h:
-
-/usr/include/bits/sigset.h:
-
-/usr/include/bits/time.h:
-
-/usr/include/sys/sysmacros.h:
-
-/usr/include/bits/pthreadtypes.h:
-
-/usr/include/bits/uio.h:
-
-/usr/include/bits/socket.h:
-
-/usr/include/bits/sockaddr.h:
-
-/usr/include/asm/socket.h:
-
-/usr/include/asm/sockios.h:
-
-/usr/include/bits/socket2.h:
-
-/usr/include/bits/in.h:
-
-/usr/include/sys/param.h:
-
-/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/limits.h:
-
-/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include-fixed/syslimits.h:
-
-/usr/include/limits.h:
-
-/usr/include/bits/posix1_lim.h:
-
-/usr/include/bits/local_lim.h:
-
-/usr/include/linux/limits.h:
-
-/usr/include/bits/posix2_lim.h:
-
-/usr/include/linux/param.h:
-
-/usr/include/asm/param.h:
-
-getgateway.h:
-
-declspec.h:
diff --git a/libportfwd/third-party/libnatpmp/.deps/natpmp.Po b/libportfwd/third-party/libnatpmp/.deps/natpmp.Po
deleted file mode 100644
index aeefa79c1..000000000
--- a/libportfwd/third-party/libnatpmp/.deps/natpmp.Po
+++ /dev/null
@@ -1,134 +0,0 @@
-natpmp.o: natpmp.c /usr/include/string.h /usr/include/features.h \
-  /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
-  /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
-  /usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h \
-  /usr/include/bits/string.h /usr/include/bits/string2.h \
-  /usr/include/endian.h /usr/include/bits/endian.h \
-  /usr/include/bits/byteswap.h /usr/include/bits/types.h \
-  /usr/include/bits/typesizes.h /usr/include/stdlib.h \
-  /usr/include/bits/string3.h /usr/include/time.h \
-  /usr/include/bits/time.h /usr/include/sys/time.h \
-  /usr/include/sys/select.h /usr/include/bits/select.h \
-  /usr/include/bits/sigset.h /usr/include/errno.h \
-  /usr/include/bits/errno.h /usr/include/linux/errno.h \
-  /usr/include/asm/errno.h /usr/include/asm-generic/errno.h \
-  /usr/include/asm-generic/errno-base.h /usr/include/unistd.h \
-  /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
-  /usr/include/getopt.h /usr/include/bits/unistd.h /usr/include/fcntl.h \
-  /usr/include/bits/fcntl.h /usr/include/sys/types.h \
-  /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
-  /usr/include/bits/fcntl2.h /usr/include/sys/socket.h \
-  /usr/include/sys/uio.h /usr/include/bits/uio.h \
-  /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \
-  /usr/include/asm/socket.h /usr/include/asm/sockios.h \
-  /usr/include/bits/socket2.h natpmp.h /usr/include/netinet/in.h \
-  /usr/include/stdint.h /usr/include/bits/wchar.h /usr/include/bits/in.h \
-  getgateway.h declspec.h
-
-/usr/include/string.h:
-
-/usr/include/features.h:
-
-/usr/include/sys/cdefs.h:
-
-/usr/include/bits/wordsize.h:
-
-/usr/include/gnu/stubs.h:
-
-/usr/include/gnu/stubs-64.h:
-
-/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/stddef.h:
-
-/usr/include/bits/string.h:
-
-/usr/include/bits/string2.h:
-
-/usr/include/endian.h:
-
-/usr/include/bits/endian.h:
-
-/usr/include/bits/byteswap.h:
-
-/usr/include/bits/types.h:
-
-/usr/include/bits/typesizes.h:
-
-/usr/include/stdlib.h:
-
-/usr/include/bits/string3.h:
-
-/usr/include/time.h:
-
-/usr/include/bits/time.h:
-
-/usr/include/sys/time.h:
-
-/usr/include/sys/select.h:
-
-/usr/include/bits/select.h:
-
-/usr/include/bits/sigset.h:
-
-/usr/include/errno.h:
-
-/usr/include/bits/errno.h:
-
-/usr/include/linux/errno.h:
-
-/usr/include/asm/errno.h:
-
-/usr/include/asm-generic/errno.h:
-
-/usr/include/asm-generic/errno-base.h:
-
-/usr/include/unistd.h:
-
-/usr/include/bits/posix_opt.h:
-
-/usr/include/bits/confname.h:
-
-/usr/include/getopt.h:
-
-/usr/include/bits/unistd.h:
-
-/usr/include/fcntl.h:
-
-/usr/include/bits/fcntl.h:
-
-/usr/include/sys/types.h:
-
-/usr/include/sys/sysmacros.h:
-
-/usr/include/bits/pthreadtypes.h:
-
-/usr/include/bits/fcntl2.h:
-
-/usr/include/sys/socket.h:
-
-/usr/include/sys/uio.h:
-
-/usr/include/bits/uio.h:
-
-/usr/include/bits/socket.h:
-
-/usr/include/bits/sockaddr.h:
-
-/usr/include/asm/socket.h:
-
-/usr/include/asm/sockios.h:
-
-/usr/include/bits/socket2.h:
-
-natpmp.h:
-
-/usr/include/netinet/in.h:
-
-/usr/include/stdint.h:
-
-/usr/include/bits/wchar.h:
-
-/usr/include/bits/in.h:
-
-getgateway.h:
-
-declspec.h:
diff --git a/libportfwd/third-party/libnatpmp/README b/libportfwd/third-party/libnatpmp/README
deleted file mode 100644
index 50fdd1093..000000000
--- a/libportfwd/third-party/libnatpmp/README
+++ /dev/null
@@ -1,4 +0,0 @@
-libnatpmp is written by Thomas Bernard.
-Its homepage is http://miniupnp.tuxfamily.org/libnatpmp.html
-This code is from the libnatpmp-20090310 snapshot
-
diff --git a/libportfwd/third-party/miniupnpc-20090605/Changelog.txt b/libportfwd/third-party/miniupnpc-1.4.20100609/Changelog.txt
similarity index 67%
rename from libportfwd/third-party/miniupnpc-20090605/Changelog.txt
rename to libportfwd/third-party/miniupnpc-1.4.20100609/Changelog.txt
index e34543fec..dc8218b1c 100644
--- a/libportfwd/third-party/miniupnpc-20090605/Changelog.txt
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/Changelog.txt
@@ -1,6 +1,106 @@
-$Id: Changelog.txt,v 1.80 2009/04/17 21:21:19 nanard Exp $
+$Id: Changelog.txt,v 1.117 2010/06/09 10:59:08 nanard Exp $
 miniUPnP client Changelog.
 
+2010/06/09:
+  update to python module to match modification made on 2010/04/05
+  update to Java test code to match modification made on 2010/04/05
+  all UPNP_* function now return an error if the SOAP request failed
+  at HTTP level.
+
+2010/04/17:
+  Using GetBestRoute() under win32 in order to find the
+  right interface to use.
+
+2010/04/12:
+  Retrying with HTTP/1.1 if HTTP/1.0 failed. see
+  http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703
+
+2010/04/07:
+  avoid returning duplicates in upnpDiscover()
+
+2010/04/05:
+  Create a connecthostport.h/.c with connecthostport() function
+  and use it in miniwget and miniupnpc.
+  Use getnameinfo() instead of inet_ntop or inet_ntoa
+  Work to make miniupnpc IPV6 compatible...
+  Add java test code.
+  Big changes in order to support device having both WANIPConnection
+  and WANPPPConnection.
+
+2010/04/04:
+  Use getaddrinfo() instead of gethostbyname() in miniwget.
+
+2010/01/06:
+  #define _DARWIN_C_SOURCE for Mac OS X
+
+2009/12/19:
+  Improve MinGW32 build
+
+2009/12/11:
+  adding a MSVC9 project to build the static library and executable
+
+2009/12/10:
+  Fixing some compilation stuff for Windows/MinGW
+
+2009/12/07:
+  adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS
+  some fixes for Windows when using virtual ethernet adapters (it is the
+  case with VMWare installed).
+
+2009/12/04:
+  some fixes for AmigaOS compilation
+  Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked
+  transfer encoding)
+
+2009/12/03:
+  updating printIDG and testigddescparse.c for debug.
+  modifications to compile under AmigaOS
+  adding a testminiwget program
+  Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked
+  transfer encoding
+
+2009/11/26:
+  fixing updateminiupnpcstrings.sh to take into account
+  which command that does not return an error code.
+
+VERSION 1.4 : released 2009/10/30
+
+2009/10/16:
+  using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module.
+
+2009/10/10:
+  Some fixes for compilation under Solaris
+  compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464
+
+2009/09/21:
+  fixing the code to ignore EINTR during connect() calls.
+
+2009/08/07:
+  Set socket timeout for connect()
+  Some cleanup in miniwget.c
+
+2009/08/04:
+  remove multiple redirections with -d in upnpc.c
+  Print textual error code in upnpc.c
+  Ignore EINTR during the connect() and poll() calls.
+
+2009/07/29:
+  fix in updateminiupnpcstrings.sh if OS name contains "/"
+  Sending a correct value for MX: field in SSDP request
+
+2009/07/20:
+  Change the Makefile to compile under Mac OS X
+  Fixed a stackoverflow in getDevicesFromMiniSSDPD()
+
+2009/07/09:
+  Compile under Haiku
+  generate miniupnpcstrings.h.in from miniupnpcstrings.h
+
+2009/06/04:
+  patching to compile under CygWin and cross compile for minGW
+
+VERSION 1.3 :
+
 2009/04/17:
   updating python module
   Use strtoull() when using C99
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE b/libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE
new file mode 100644
index 000000000..2b561fb4f
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2005-2009, Thomas BERNARD 
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * The name of the author may not be used to endorse or promote products
+	  derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/libportfwd/third-party/miniupnpc-20090605/README b/libportfwd/third-party/miniupnpc-1.4.20100609/README
similarity index 80%
rename from libportfwd/third-party/miniupnpc-20090605/README
rename to libportfwd/third-party/miniupnpc-1.4.20100609/README
index 3aa2a361b..429507062 100644
--- a/libportfwd/third-party/miniupnpc-20090605/README
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/README
@@ -1,9 +1,9 @@
 Project: miniupnp
 Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
 Author: Thomas Bernard
-Copyright (c) 2005-2008 Thomas Bernard
+Copyright (c) 2005-2009 Thomas Bernard
 This software is subject to the conditions detailed in the
-LICENCE file provided within this distribution.
+LICENSE file provided within this distribution.
 
 For the comfort of Win32 users, bsdqueue.h is included in the distribution.
 Its licence is included in the header of the file.
@@ -11,10 +11,12 @@ bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system.
 
 * miniupnp Client *
 
-To compile, simply run 'gmake' (could be 'make').
+To compile, simply run 'gmake' (could be 'make' on your system).
 Under win32, to compile with MinGW, type "mingw32make.bat".
 The compilation is known to work under linux, FreeBSD,
-OpenBSD, MacOS X and cygwin.
+OpenBSD, MacOS X, AmigaOS and cygwin.
+The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
+
 To install the library and headers on the system use :
 > su
 > make install
@@ -25,7 +27,7 @@ alternatively, to install in a specific location, use :
 
 upnpc.c is a sample client using the libminiupnpc.
 To use the libminiupnpc in your application, link it with
-libminiupnpc.a and use the following functions found in miniupnpc.h,
+libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
 upnpcommands.h and miniwget.h :
 - upnpDiscover()
 - miniwget()
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/VERSION b/libportfwd/third-party/miniupnpc-1.4.20100609/VERSION
new file mode 100644
index 000000000..c068b2447
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/VERSION
@@ -0,0 +1 @@
+1.4
diff --git a/libportfwd/third-party/miniupnpc-20090605/bsdqueue.h b/libportfwd/third-party/miniupnpc-1.4.20100609/bsdqueue.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/bsdqueue.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/bsdqueue.h
diff --git a/libportfwd/third-party/miniupnpc-20090605/codelength.h b/libportfwd/third-party/miniupnpc-1.4.20100609/codelength.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/codelength.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/codelength.h
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c
new file mode 100644
index 000000000..e52eed09c
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.c
@@ -0,0 +1,221 @@
+/* $Id: connecthostport.c,v 1.2 2010/04/05 00:08:15 nanard Exp $ */
+/* Project : miniupnp
+ * Author : Thomas Bernard
+ * Copyright (c) 2010 Thomas Bernard
+ * This software is subject to the conditions detailed in the
+ * LICENCE file provided in this distribution. */
+
+/* use getaddrinfo() or gethostbyname()
+ * uncomment the following line in order to use gethostbyname() */
+/* #define USE_GETHOSTBYNAME */
+
+#include <string.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#define snprintf _snprintf
+#define herror
+#define socklen_t int
+#else /* #ifdef WIN32 */
+#include <unistd.h>
+#include <errno.h>
+#define closesocket close
+#include <netdb.h>
+/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
+ * during the connect() call */
+#define MINIUPNPC_IGNORE_EINTR
+#ifndef USE_GETHOSTBYNAME
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif /* #ifndef USE_GETHOSTBYNAME */
+#endif /* #else WIN32 */
+
+/* definition of PRINT_SOCKET_ERROR */
+#ifdef WIN32
+#define PRINT_SOCKET_ERROR(x)    printf("Socket error: %s, %d\n", x, WSAGetLastError());
+#else
+#define PRINT_SOCKET_ERROR(x) perror(x)
+#endif
+
+#if defined(__amigaos__) || defined(__amigaos4__)
+#define herror(A) printf("%s\n", A)
+#endif
+
+#include "connecthostport.h"
+
+/* connecthostport()
+ * return a socket connected (TCP) to the host and port
+ * or -1 in case of error */
+int connecthostport(const char * host, unsigned short port)
+{
+	int s, n;
+#ifdef USE_GETHOSTBYNAME
+	struct sockaddr_in dest;
+	struct hostent *hp;
+#else /* #ifdef USE_GETHOSTBYNAME */
+	char port_str[8];
+	struct addrinfo *ai, *p;
+	struct addrinfo hints;
+#endif /* #ifdef USE_GETHOSTBYNAME */
+#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
+	struct timeval timeout;
+#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
+	
+#ifdef USE_GETHOSTBYNAME
+	hp = gethostbyname(host);
+	if(hp == NULL)
+	{
+		herror(host);
+		return -1;
+	}
+	memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
+	memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
+	s = socket(PF_INET, SOCK_STREAM, 0);
+	if(s < 0)
+	{
+		PRINT_SOCKET_ERROR("socket");
+		return -1;
+	}
+#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
+	/* setting a 3 seconds timeout for the connect() call */
+	timeout.tv_sec = 3;
+	timeout.tv_usec = 0;
+	if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
+	{
+		PRINT_SOCKET_ERROR("setsockopt");
+	}
+	timeout.tv_sec = 3;
+	timeout.tv_usec = 0;
+	if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
+	{
+		PRINT_SOCKET_ERROR("setsockopt");
+	}
+#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
+	dest.sin_family = AF_INET;
+	dest.sin_port = htons(port);
+	n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
+#ifdef MINIUPNPC_IGNORE_EINTR
+	while(n < 0 && errno == EINTR)
+	{
+		socklen_t len;
+		fd_set wset;
+		int err;
+		FD_ZERO(&wset);
+		FD_SET(s, &wset);
+		if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
+			continue;
+		/*len = 0;*/
+		/*n = getpeername(s, NULL, &len);*/
+		len = sizeof(err);
+		if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
+			PRINT_SOCKET_ERROR("getsockopt");
+			closesocket(s);
+			return -1;
+		}
+		if(err != 0) {
+			errno = err;
+			n = -1;
+		}
+	}
+#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
+	if(n<0)
+	{
+		PRINT_SOCKET_ERROR("connect");
+		closesocket(s);
+		return -1;
+	}
+#else /* #ifdef USE_GETHOSTBYNAME */
+	/* use getaddrinfo() instead of gethostbyname() */
+	memset(&hints, 0, sizeof(hints));
+	/* hints.ai_flags = AI_ADDRCONFIG; */
+#ifdef AI_NUMERICSERV
+	hints.ai_flags = AI_NUMERICSERV;
+#endif
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
+	/* hints.ai_protocol = IPPROTO_TCP; */
+	snprintf(port_str, sizeof(port_str), "%hu", port);
+	n = getaddrinfo(host, port_str, &hints, &ai);
+	if(n != 0)
+	{
+#ifdef WIN32
+		fprintf(stderr, "getaddrinfo() error : %d\n", n);
+#else
+		fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
+#endif
+		return -1;
+	}
+	s = -1;
+	for(p = ai; p; p = p->ai_next)
+	{
+		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+		if(s < 0)
+			continue;
+#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
+		/* setting a 3 seconds timeout for the connect() call */
+		timeout.tv_sec = 3;
+		timeout.tv_usec = 0;
+		if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
+		{
+			PRINT_SOCKET_ERROR("setsockopt");
+		}
+		timeout.tv_sec = 3;
+		timeout.tv_usec = 0;
+		if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
+		{
+			PRINT_SOCKET_ERROR("setsockopt");
+		}
+#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
+		n = connect(s, p->ai_addr, p->ai_addrlen);
+#ifdef MINIUPNPC_IGNORE_EINTR
+		while(n < 0 && errno == EINTR)
+		{
+			socklen_t len;
+			fd_set wset;
+			int err;
+			FD_ZERO(&wset);
+			FD_SET(s, &wset);
+			if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
+				continue;
+			/*len = 0;*/
+			/*n = getpeername(s, NULL, &len);*/
+			len = sizeof(err);
+			if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
+				PRINT_SOCKET_ERROR("getsockopt");
+				closesocket(s);
+				freeaddrinfo(ai);
+				return -1;
+			}
+			if(err != 0) {
+				errno = err;
+				n = -1;
+			}
+		}
+#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
+		if(n < 0)
+		{
+			closesocket(s);
+			continue;
+		}
+		else
+		{
+			break;
+		}
+	}
+	freeaddrinfo(ai);
+	if(s < 0)
+	{
+		PRINT_SOCKET_ERROR("socket");
+		return -1;
+	}
+	if(n < 0)
+	{
+		PRINT_SOCKET_ERROR("connect");
+		return -1;
+	}
+#endif /* #ifdef USE_GETHOSTBYNAME */
+	return s;
+}
+
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h
new file mode 100644
index 000000000..57e24eb27
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/connecthostport.h
@@ -0,0 +1,17 @@
+/* $Id: connecthostport.h,v 1.1 2010/04/04 23:21:03 nanard Exp $ */
+/* Project: miniupnp
+ * http://miniupnp.free.fr/
+ * Author: Thomas Bernard
+ * Copyright (c) 2010 Thomas Bernard
+ * This software is subjects to the conditions detailed
+ * in the LICENCE file provided within this distribution */
+#ifndef __CONNECTHOSTPORT_H__
+#define __CONNECTHOSTPORT_H__
+
+/* connecthostport()
+ * return a socket connected (TCP) to the host and port
+ * or -1 in case of error */
+int connecthostport(const char * host, unsigned short port);
+
+#endif
+
diff --git a/libportfwd/third-party/miniupnpc-20090605/declspec.h b/libportfwd/third-party/miniupnpc-1.4.20100609/declspec.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/declspec.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/declspec.h
diff --git a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.c
similarity index 54%
rename from libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.c
index e839ff4c1..7440e9f5b 100644
--- a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.c
@@ -1,18 +1,15 @@
-/* $Id: igd_desc_parse.c,v 1.8 2008/04/23 11:51:06 nanard Exp $ */
+/* $Id: igd_desc_parse.c,v 1.10 2010/04/05 20:36:59 nanard Exp $ */
 /* Project : miniupnp
  * http://miniupnp.free.fr/
  * Author : Thomas Bernard
- * Copyright (c) 2005-2008 Thomas Bernard
+ * Copyright (c) 2005-2010 Thomas Bernard
  * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
+ * LICENCE file provided in this distribution. */
+
 #include "igd_desc_parse.h"
 #include <stdio.h>
 #include <string.h>
 
-/* TODO : rewrite this code so it correctly handle descriptions with
- * both WANIPConnection and/or WANPPPConnection */
-
 /* Start element handler :
  * update nesting level counter and copy element name */
 void IGDstartelt(void * d, const char * name, int l)
@@ -22,10 +19,10 @@ void IGDstartelt(void * d, const char * name, int l)
 	datas->cureltname[l] = '\0';
 	datas->level++;
 	if( (l==7) && !memcmp(name, "service", l) ) {
-		datas->controlurl_tmp[0] = '\0';
-		datas->eventsuburl_tmp[0] = '\0';
-		datas->scpdurl_tmp[0] = '\0';
-		datas->servicetype_tmp[0] = '\0';
+		datas->tmp.controlurl[0] = '\0';
+		datas->tmp.eventsuburl[0] = '\0';
+		datas->tmp.scpdurl[0] = '\0';
+		datas->tmp.servicetype[0] = '\0';
 	}
 }
 
@@ -46,20 +43,18 @@ void IGDendelt(void * d, const char * name, int l)
 				"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
 			datas->state ++;
 		*/
-		if(0==strcmp(datas->servicetype_tmp,
+		if(0==strcmp(datas->tmp.servicetype,
 				"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
-			memcpy(datas->controlurl_CIF, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE);
-			memcpy(datas->eventsuburl_CIF, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE);
-			memcpy(datas->scpdurl_CIF, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE);
-			memcpy(datas->servicetype_CIF, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE);
-		} else if(0==strcmp(datas->servicetype_tmp,
+			memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
+		} else if(0==strcmp(datas->tmp.servicetype,
 				"urn:schemas-upnp-org:service:WANIPConnection:1")
-				 || 0==strcmp(datas->servicetype_tmp,
+				 || 0==strcmp(datas->tmp.servicetype,
 				"urn:schemas-upnp-org:service:WANPPPConnection:1") ) {
-			memcpy(datas->controlurl, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE);
-			memcpy(datas->eventsuburl, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE);
-			memcpy(datas->scpdurl, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE);
-			memcpy(datas->servicetype, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE);
+			if(datas->first.servicetype[0] == '\0') {
+				memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service));
+			} else {
+				memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service));
+			}
 		}
 	}
 }
@@ -75,13 +70,13 @@ void IGDdata(void * d, const char * data, int l)
 	if( !strcmp(datas->cureltname, "URLBase") )
 		dstmember = datas->urlbase;
 	else if( !strcmp(datas->cureltname, "serviceType") )
-		dstmember = datas->servicetype_tmp;
+		dstmember = datas->tmp.servicetype;
 	else if( !strcmp(datas->cureltname, "controlURL") )
-		dstmember = datas->controlurl_tmp;
+		dstmember = datas->tmp.controlurl;
 	else if( !strcmp(datas->cureltname, "eventSubURL") )
-		dstmember = datas->eventsuburl_tmp;
+		dstmember = datas->tmp.eventsuburl;
 	else if( !strcmp(datas->cureltname, "SCPDURL") )
-		dstmember = datas->scpdurl_tmp;
+		dstmember = datas->tmp.scpdurl;
 /*	else if( !strcmp(datas->cureltname, "deviceType") )
 		dstmember = datas->devicetype_tmp;*/
 	if(dstmember)
@@ -95,19 +90,25 @@ void IGDdata(void * d, const char * data, int l)
 
 void printIGD(struct IGDdatas * d)
 {
-	printf("urlbase = %s\n", d->urlbase);
+	printf("urlbase = '%s'\n", d->urlbase);
 	printf("WAN Device (Common interface config) :\n");
-	/*printf(" deviceType = %s\n", d->devicetype_CIF);*/
-	printf(" serviceType = %s\n", d->servicetype_CIF);
-	printf(" controlURL = %s\n", d->controlurl_CIF);
-	printf(" eventSubURL = %s\n", d->eventsuburl_CIF);
-	printf(" SCPDURL = %s\n", d->scpdurl_CIF);
+	/*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/
+	printf(" serviceType = '%s'\n", d->CIF.servicetype);
+	printf(" controlURL = '%s'\n", d->CIF.controlurl);
+	printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
+	printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
 	printf("WAN Connection Device (IP or PPP Connection):\n");
-	/*printf(" deviceType = %s\n", d->devicetype);*/
-	printf(" servicetype = %s\n", d->servicetype);
-	printf(" controlURL = %s\n", d->controlurl);
-	printf(" eventSubURL = %s\n", d->eventsuburl);
-	printf(" SCPDURL = %s\n", d->scpdurl);
+	/*printf(" deviceType = '%s'\n", d->first.devicetype);*/
+	printf(" servicetype = '%s'\n", d->first.servicetype);
+	printf(" controlURL = '%s'\n", d->first.controlurl);
+	printf(" eventSubURL = '%s'\n", d->first.eventsuburl);
+	printf(" SCPDURL = '%s'\n", d->first.scpdurl);
+	printf("secondary WAN Connection Device (IP or PPP Connection):\n");
+	/*printf(" deviceType = '%s'\n", d->second.devicetype);*/
+	printf(" servicetype = '%s'\n", d->second.servicetype);
+	printf(" controlURL = '%s'\n", d->second.controlurl);
+	printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
+	printf(" SCPDURL = '%s'\n", d->second.scpdurl);
 }
 
 
diff --git a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.h b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.h
similarity index 65%
rename from libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.h
index aabcb087d..40cca60b2 100644
--- a/libportfwd/third-party/miniupnpc-20090605/igd_desc_parse.h
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/igd_desc_parse.h
@@ -1,8 +1,8 @@
-/* $Id: igd_desc_parse.h,v 1.6 2008/04/23 11:51:07 nanard Exp $ */
+/* $Id: igd_desc_parse.h,v 1.7 2010/04/05 20:36:59 nanard Exp $ */
 /* Project : miniupnp
  * http://miniupnp.free.fr/
  * Author : Thomas Bernard
- * Copyright (c) 2005-2008 Thomas Bernard
+ * Copyright (c) 2005-2010 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  * */
@@ -12,30 +12,28 @@
 /* Structure to store the result of the parsing of UPnP
  * descriptions of Internet Gateway Devices */
 #define MINIUPNPC_URL_MAXSIZE (128)
+struct IGDdatas_service {
+	char controlurl[MINIUPNPC_URL_MAXSIZE];
+	char eventsuburl[MINIUPNPC_URL_MAXSIZE];
+	char scpdurl[MINIUPNPC_URL_MAXSIZE];
+	char servicetype[MINIUPNPC_URL_MAXSIZE];
+	/*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
+};
+
 struct IGDdatas {
 	char cureltname[MINIUPNPC_URL_MAXSIZE];
 	char urlbase[MINIUPNPC_URL_MAXSIZE];
 	int level;
 	/*int state;*/
 	/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
-	char controlurl_CIF[MINIUPNPC_URL_MAXSIZE];
-	char eventsuburl_CIF[MINIUPNPC_URL_MAXSIZE];
-	char scpdurl_CIF[MINIUPNPC_URL_MAXSIZE];
-	char servicetype_CIF[MINIUPNPC_URL_MAXSIZE];
-	/*char devicetype_CIF[MINIUPNPC_URL_MAXSIZE];*/
+	struct IGDdatas_service CIF;
 	/* "urn:schemas-upnp-org:service:WANIPConnection:1"
 	 * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
-	char controlurl[MINIUPNPC_URL_MAXSIZE];
-	char eventsuburl[MINIUPNPC_URL_MAXSIZE];
-	char scpdurl[MINIUPNPC_URL_MAXSIZE];
-	char servicetype[MINIUPNPC_URL_MAXSIZE];
-	/*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
+	struct IGDdatas_service first;
+	/* if both WANIPConnection and WANPPPConnection are present */
+	struct IGDdatas_service second;
 	/* tmp */
-	char controlurl_tmp[MINIUPNPC_URL_MAXSIZE];
-	char eventsuburl_tmp[MINIUPNPC_URL_MAXSIZE];
-	char scpdurl_tmp[MINIUPNPC_URL_MAXSIZE];
-	char servicetype_tmp[MINIUPNPC_URL_MAXSIZE];
-	/*char devicetype_tmp[MINIUPNPC_URL_MAXSIZE];*/
+	struct IGDdatas_service tmp;
 };
 
 void IGDstartelt(void *, const char *, int);
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java b/libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java
new file mode 100644
index 000000000..999001001
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/java/JavaBridgeTest.java
@@ -0,0 +1,89 @@
+import java.nio.ByteBuffer;
+import fr.free.miniupnp.*;
+
+/**
+ *
+ * @author syuu
+ */
+public class JavaBridgeTest {
+    public static void main(String[] args) {
+        int UPNP_DELAY = 2000;
+        MiniupnpcLibrary miniupnpc = MiniupnpcLibrary.INSTANCE;
+        UPNPDev devlist = null;
+        UPNPUrls urls = new UPNPUrls();
+        IGDdatas data = new IGDdatas();
+        ByteBuffer lanaddr = ByteBuffer.allocate(16);
+        ByteBuffer intClient = ByteBuffer.allocate(16);
+        ByteBuffer intPort = ByteBuffer.allocate(6);
+        int ret;
+        int i;
+
+        if(args.length < 2) {
+            System.err.println("Usage : java [...] JavaBridgeTest port protocol");
+            System.out.println("  port is numeric, protocol is TCP or UDP");
+            return;
+        }
+
+        devlist = miniupnpc.upnpDiscover(UPNP_DELAY, (String) null, (String) null, 0);
+        if (devlist != null) {
+            System.out.println("List of UPNP devices found on the network :");
+            for (UPNPDev device = devlist; device != null; device = device.pNext) {
+                System.out.println("desc: " + device.descURL.getString(0) + " st: " + device.st.getString(0));
+            }
+            if ((i = miniupnpc.UPNP_GetValidIGD(devlist, urls, data, lanaddr, 16)) != 0) {
+                switch (i) {
+                    case 1:
+                        System.out.println("Found valid IGD : " + urls.controlURL.getString(0));
+                        break;
+                    case 2:
+                        System.out.println("Found a (not connected?) IGD : " + urls.controlURL.getString(0));
+                        System.out.println("Trying to continue anyway");
+                        break;
+                    case 3:
+                        System.out.println("UPnP device found. Is it an IGD ? : " + urls.controlURL.getString(0));
+                        System.out.println("Trying to continue anyway");
+                        break;
+                    default:
+                        System.out.println("Found device (igd ?) : " + urls.controlURL.getString(0));
+                        System.out.println("Trying to continue anyway");
+
+                }
+                System.out.println("Local LAN ip address : " + new String(lanaddr.array()));
+                ByteBuffer externalAddress = ByteBuffer.allocate(16);
+                miniupnpc.UPNP_GetExternalIPAddress(urls.controlURL.getString(0),
+                        new String(data.first.servicetype), externalAddress);
+                System.out.println("ExternalIPAddress = " + new String(externalAddress.array()));
+                ret = miniupnpc.UPNP_AddPortMapping(
+                        urls.controlURL.getString(0), // controlURL
+                        new String(data.first.servicetype), // servicetype
+                        args[0], // external Port
+                        args[0], // internal Port
+                        new String(lanaddr.array()), // internal client
+                        "added via miniupnpc/JAVA !", // description
+                        args[1], // protocol UDP or TCP
+                        null); // remote host (useless)
+                if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
+                    System.out.println("AddPortMapping() failed with code " + ret);
+                ret = miniupnpc.UPNP_GetSpecificPortMappingEntry(
+                        urls.controlURL.getString(0), new String(data.first.servicetype),
+                        args[0], args[1], intClient, intPort);
+                if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
+                    System.out.println("GetSpecificPortMappingEntry() failed with code " + ret);
+                System.out.println("InternalIP:Port = " +
+                        new String(intClient.array()) + ":" + new String(intPort.array()));
+                ret = miniupnpc.UPNP_DeletePortMapping(
+                        urls.controlURL.getString(0),
+                        new String(data.first.servicetype),
+                        args[0], args[1], null);
+                if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
+                    System.out.println("DelPortMapping() failed with code " + ret);
+                miniupnpc.FreeUPNPUrls(urls);
+            } else {
+                System.out.println("No valid UPNP Internet Gateway Device found.");
+            }
+            miniupnpc.freeUPNPDevlist(devlist);
+        } else {
+            System.out.println("No IGD UPnP Device found on the network !\n");
+        }
+    }
+}
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh b/libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh
new file mode 100755
index 000000000..c997baf9e
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/java/testjava.sh
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+JAVA=java
+JAVAC=javac
+
+$JAVAC -cp miniupnpc_Linux.jar JavaBridgeTest.java
+$JAVA -cp miniupnpc_Linux.jar:. JavaBridgeTest 12345 UDP
+
diff --git a/libportfwd/third-party/miniupnpc-20090605/man3/miniupnpc.3 b/libportfwd/third-party/miniupnpc-1.4.20100609/man3/miniupnpc.3
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/man3/miniupnpc.3
rename to libportfwd/third-party/miniupnpc-1.4.20100609/man3/miniupnpc.3
diff --git a/libportfwd/third-party/miniupnpc-20090605/mingw32make.bat b/libportfwd/third-party/miniupnpc-1.4.20100609/mingw32make.bat
similarity index 81%
rename from libportfwd/third-party/miniupnpc-20090605/mingw32make.bat
rename to libportfwd/third-party/miniupnpc-1.4.20100609/mingw32make.bat
index 3e59be59b..c5d3cc4ff 100644
--- a/libportfwd/third-party/miniupnpc-20090605/mingw32make.bat
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/mingw32make.bat
@@ -1,5 +1,6 @@
 @mingw32-make -f Makefile.mingw %1
 @if errorlevel 1 goto end
+@if not exist upnpc-static.exe goto end
 @strip upnpc-static.exe
 @upx --best upnpc-static.exe
 @strip upnpc-shared.exe
diff --git a/libportfwd/third-party/miniupnpc-20090605/minisoap.c b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.c
similarity index 85%
rename from libportfwd/third-party/miniupnpc-20090605/minisoap.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.c
index 04b1a92b8..9afacb787 100644
--- a/libportfwd/third-party/miniupnpc-20090605/minisoap.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.c
@@ -1,7 +1,7 @@
-/* $Id: minisoap.c,v 1.16 2008/10/11 16:39:29 nanard Exp $ */
+/* $Id: minisoap.c,v 1.19 2010/04/12 20:39:41 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
+ * Copyright (c) 2005-2009 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  *
@@ -75,7 +75,8 @@ int soapPostSubmit(int fd,
 				   const char * host,
 				   unsigned short port,
 				   const char * action,
-				   const char * body)
+				   const char * body,
+				   const char * httpversion)
 {
 	int bodysize;
 	char headerbuf[512];
@@ -84,14 +85,16 @@ int soapPostSubmit(int fd,
 	bodysize = (int)strlen(body);
 	/* We are not using keep-alive HTTP connections.
 	 * HTTP/1.1 needs the header Connection: close to do that.
-	 * This is the default with HTTP/1.0 */
+	 * This is the default with HTTP/1.0
+	 * Using HTTP/1.1 means we need to support chunked transfer-encoding :
+	 * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked
+	 * transfer encoding. */
     /* Connection: Close is normally there only in HTTP/1.1 but who knows */
 	portstr[0] = '\0';
 	if(port != 80)
 		snprintf(portstr, sizeof(portstr), ":%hu", port);
 	headerssize = snprintf(headerbuf, sizeof(headerbuf),
-                       "POST %s HTTP/1.1\r\n"
-/*                       "POST %s HTTP/1.0\r\n"*/
+                       "POST %s HTTP/%s\r\n"
 	                   "Host: %s%s\r\n"
 					   "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
 	                   "Content-Length: %d\r\n"
@@ -101,7 +104,7 @@ int soapPostSubmit(int fd,
 					   "Cache-Control: no-cache\r\n"	/* ??? */
 					   "Pragma: no-cache\r\n"
 					   "\r\n",
-					   url, host, portstr, bodysize, action);
+					   url, httpversion, host, portstr, bodysize, action);
 #ifdef DEBUG
 	printf("SOAP request : headersize=%d bodysize=%d\n",
 	       headerssize, bodysize);
diff --git a/libportfwd/third-party/miniupnpc-20090605/minisoap.h b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.h
similarity index 77%
rename from libportfwd/third-party/miniupnpc-20090605/minisoap.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.h
index 9fa297fd3..696725f62 100644
--- a/libportfwd/third-party/miniupnpc-20090605/minisoap.h
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minisoap.h
@@ -1,4 +1,4 @@
-/* $Id: minisoap.h,v 1.3 2006/11/19 22:32:34 nanard Exp $ */
+/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
  * Copyright (c) 2005 Thomas Bernard
@@ -9,7 +9,7 @@
 
 /*int httpWrite(int, const char *, int, const char *);*/
 int soapPostSubmit(int, const char *, const char *, unsigned short,
-				   const char *, const char *);
+		   const char *, const char *, const char *);
 
 #endif
 
diff --git a/libportfwd/third-party/miniupnpc-20090605/minissdpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.c
similarity index 80%
rename from libportfwd/third-party/miniupnpc-20090605/minissdpc.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.c
index 557b65acf..33ffa3ab5 100644
--- a/libportfwd/third-party/miniupnpc-20090605/minissdpc.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.c
@@ -1,7 +1,7 @@
-/* $Id: minissdpc.c,v 1.7 2008/12/18 17:45:48 nanard Exp $ */
+/* $Id: minissdpc.c,v 1.13 2009/12/04 16:57:29 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas BERNARD
- * copyright (c) 2005-2008 Thomas Bernard
+ * copyright (c) 2005-2009 Thomas Bernard
  * This software is subjet to the conditions detailed in the
  * provided LICENCE file. */
 /*#include <syslog.h>*/
@@ -10,15 +10,23 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
+#if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__)
 #ifdef WIN32
 #include <winsock2.h>
-#include <Ws2tcpip.h>
+#include <ws2tcpip.h>
 #include <io.h>
+#endif
+#if defined(__amigaos__) || defined(__amigaos4__)
+#include <sys/socket.h>
+#endif
+#if defined(__amigaos__)
+#define uint16_t unsigned short
+#endif
 /* Hack */
-#define UNIX_PATH_LEN 108
+#define UNIX_PATH_LEN   108
 struct sockaddr_un {
-    uint16_t sun_family;
-    char sun_path[UNIX_PATH_LEN];
+  uint16_t sun_family;
+  char     sun_path[UNIX_PATH_LEN];
 };
 #else
 #include <sys/socket.h>
@@ -53,6 +61,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
 	}
 	addr.sun_family = AF_UNIX;
 	strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
+	/* TODO : check if we need to handle the EINTR */
 	if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
 	{
 		/*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
@@ -63,6 +72,12 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
 	buffer[0] = 1; /* request type 1 : request devices/services by type */
 	p = buffer + 1;
 	l = stsize;	CODELENGTH(l, p);
+	if(p + stsize > buffer + sizeof(buffer))
+	{
+		/* devtype is too long ! */
+		close(s);
+		return NULL;
+	}
 	memcpy(p, devtype, stsize);
 	p += stsize;
 	if(write(s, buffer, p - buffer) < 0)
diff --git a/libportfwd/third-party/miniupnpc-20090605/minissdpc.h b/libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/minissdpc.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minissdpc.h
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c
similarity index 62%
rename from libportfwd/third-party/miniupnpc-20090605/miniupnpc.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c
index 3794d2b07..484a17e77 100644
--- a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.c
@@ -1,42 +1,75 @@
-/* $Id: miniupnpc.c,v 1.57 2008/12/18 17:46:36 nanard Exp $ */
+/* $Id: miniupnpc.c,v 1.81 2010/04/17 22:07:59 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas BERNARD
- * copyright (c) 2005-2007 Thomas Bernard
+ * copyright (c) 2005-2010 Thomas Bernard
  * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#include <stdio.h>
+ * provided LICENSE file. */
+#define __EXTENSIONS__ 1
+#if !defined(MACOSX) && !defined(__sun)
+#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__)
+#ifndef __cplusplus
+#define _XOPEN_SOURCE 600
+#endif
+#endif
+#ifndef __BSD_VISIBLE
+#define __BSD_VISIBLE 1
+#endif
+#endif
+
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #ifdef WIN32
 /* Win32 Specific includes and defines */
 #include <winsock2.h>
-#include <Ws2tcpip.h>
+#include <ws2tcpip.h>
 #include <io.h>
+#include <IPHlpApi.h>
 #define snprintf _snprintf
 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
 #define strncasecmp _memicmp
-#else
+#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
 #define strncasecmp memicmp
-#endif
+#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
 #define MAXHOSTNAMELEN 64
-#else
+#else /* #ifdef WIN32 */
 /* Standard POSIX includes */
 #include <unistd.h>
+#if defined(__amigaos__) && !defined(__amigaos4__)
+/* Amiga OS 3 specific stuff */
+#define socklen_t int
+#else
+#include <sys/select.h>
+#endif
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <poll.h>
 #include <netdb.h>
-#define closesocket close
+#if !defined(__amigaos__) && !defined(__amigaos4__)
+#include <poll.h>
 #endif
+#include <strings.h>
+#include <errno.h>
+#define closesocket close
+#define MINIUPNPC_IGNORE_EINTR
+#endif /* #else WIN32 */
+#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
+#include <sys/time.h>
+#endif
+#if defined(__amigaos__) || defined(__amigaos4__)
+/* Amiga OS specific stuff */
+#define TIMEVAL struct timeval
+#endif
+
 #include "miniupnpc.h"
 #include "minissdpc.h"
 #include "miniwget.h"
 #include "minisoap.h"
 #include "minixml.h"
 #include "upnpcommands.h"
+#include "connecthostport.h"
 
 #ifdef WIN32
 #define PRINT_SOCKET_ERROR(x)    printf("Socket error: %s, %d\n", x, WSAGetLastError());
@@ -49,7 +82,7 @@
 #define SERVICEPREFIX2 'u'
 
 /* root description parsing */
-void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
+LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
 {
 	struct xmlparser parser;
 	/* xmlparser object */
@@ -66,7 +99,8 @@ void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
 #endif
 }
 
-/* Content-length: nnn */
+/* getcontentlenfromline() : parse the Content-Length HTTP header line.
+ * Content-length: nnn */
 static int getcontentlenfromline(const char * p, int n)
 {
 	static const char contlenstr[] = "content-length";
@@ -101,6 +135,10 @@ static int getcontentlenfromline(const char * p, int n)
 	return a;
 }
 
+/* getContentLengthAndHeaderLength()
+ * retrieve header length and content length from an HTTP response
+ * TODO : retrieve Transfer-Encoding: header value, in order to support
+ *        HTTP/1.1, chunked transfer encoding must be supported. */
 static void
 getContentLengthAndHeaderLength(char * p, int n,
                                 int * contentlen, int * headerlen)
@@ -130,17 +168,15 @@ getContentLengthAndHeaderLength(char * p, int n,
 	}
 }
 
-/* simpleUPnPcommand :
+/* simpleUPnPcommand2 :
  * not so simple !
  * return values :
  *   0 - OK
  *  -1 - error */
-int simpleUPnPcommand(int s, const char * url, const char * service,
-                      const char * action, struct UPNParg * args,
-                      char * buffer, int * bufsize)
+static int simpleUPnPcommand2(int s, const char * url, const char * service,
+		       const char * action, struct UPNParg * args,
+		       char * buffer, int * bufsize, const char * httpversion)
 {
-    if(!url) return -1;
-	struct sockaddr_in dest;
 	char hostname[MAXHOSTNAMELEN+1];
 	unsigned short port = 0;
 	char * path;
@@ -150,6 +186,7 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
 	int buffree;
     int n;
 	int contentlen, headerlen;	/* for the response */
+
 	snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
 	if(args==NULL)
 	{
@@ -218,26 +255,15 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
 	if(!parseURL(url, hostname, &port, &path)) return -1;
 	if(s<0)
 	{
-		s = socket(PF_INET, SOCK_STREAM, 0);
-		if(s<0)
+		s = connecthostport(hostname, port);
+		if(s < 0)
 		{
-			PRINT_SOCKET_ERROR("socket");
-			*bufsize = 0;
-			return -1;
-		}
-		dest.sin_family = AF_INET;
-		dest.sin_port = htons(port);
-		dest.sin_addr.s_addr = inet_addr(hostname);
-		if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr))<0)
-		{
-			PRINT_SOCKET_ERROR("connect");
-			closesocket(s);
 			*bufsize = 0;
 			return -1;
 		}
 	}
 
-	n = soapPostSubmit(s, path, hostname, port, soapact, soapbody);
+	n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
 	if(n<=0) {
 #ifdef DEBUG
 		printf("Error sending SOAP request\n");
@@ -270,6 +296,30 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
 	return 0;
 }
 
+/* simpleUPnPcommand :
+ * not so simple !
+ * return values :
+ *   0 - OK
+ *  -1 - error */
+int simpleUPnPcommand(int s, const char * url, const char * service,
+		       const char * action, struct UPNParg * args,
+		       char * buffer, int * bufsize)
+{
+	int result;
+	int origbufsize = *bufsize;
+
+	result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0");
+	if (result < 0 || *bufsize == 0)
+	{
+#if DEBUG
+	    printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
+#endif
+		*bufsize = origbufsize;
+		result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
+	}
+	return result;
+}
+
 /* parseMSEARCHReply()
  * the last 4 arguments are filled during the parsing :
  *    - location/locationsize : "location:" field of the SSDP reply packet
@@ -341,7 +391,7 @@ parseMSEARCHReply(const char * reply, int size,
  * no devices was found.
  * It is up to the caller to free the chained list
  * delay is in millisecond (poll) */
-struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
+LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
                               const char * minissdpdsock, int sameport)
 {
 	struct UPNPDev * tmp;
@@ -352,7 +402,7 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 	"HOST: " UPNP_MCAST_ADDR ":" XSTR(PORT) "\r\n"
 	"ST: %s\r\n"
 	"MAN: \"ssdp:discover\"\r\n"
-	"MX: 3\r\n"
+	"MX: %u\r\n"
 	"\r\n";
 	static const char * const deviceList[] = {
 		"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
@@ -365,9 +415,15 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 	char bufr[1536];	/* reception and emission buffer */
 	int sudp;
 	int n;
-	struct sockaddr_in sockudp_r, sockudp_w;
+	struct sockaddr sockudp_r;
+	unsigned int mx;
+	int rv;
+	struct addrinfo hints, *servinfo, *p;
+#ifdef WIN32
+	MIB_IPFORWARDROW ip_forward;
+#endif
 
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
 	/* first try to get infos from minissdpd ! */
 	if(!minissdpdsock)
 		minissdpdsock = "/var/run/minissdpd.sock";
@@ -392,17 +448,86 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 		PRINT_SOCKET_ERROR("socket");
 		return NULL;
 	}
-    /* reception */
-    memset(&sockudp_r, 0, sizeof(struct sockaddr_in));
-    sockudp_r.sin_family = AF_INET;
-	if(sameport)
-    	sockudp_r.sin_port = htons(PORT);
-    sockudp_r.sin_addr.s_addr = INADDR_ANY;
-    /* emission */
-    memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
-    sockudp_w.sin_family = AF_INET;
-    sockudp_w.sin_port = htons(PORT);
-    sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
+	/* reception */
+	memset(&sockudp_r, 0, sizeof(struct sockaddr));
+	if(0/*ipv6*/) {
+		struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
+		p->sin6_family = AF_INET6;
+		if(sameport)
+			p->sin6_port = htons(PORT);
+		p->sin6_addr = in6addr_any;//IN6ADDR_ANY_INIT;/*INADDR_ANY;*/
+	} else {
+		struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
+		p->sin_family = AF_INET;
+		if(sameport)
+			p->sin_port = htons(PORT);
+		p->sin_addr.s_addr = INADDR_ANY;
+	}
+#if 0
+	/* emission */
+	memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
+	sockudp_w.sin_family = AF_INET;
+	sockudp_w.sin_port = htons(PORT);
+	sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
+#endif
+#ifdef WIN32
+/* This code could help us to use the right Network interface for 
+ * SSDP multicast traffic */
+/* Get IP associated with the index given in the ip_forward struct
+ * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
+	if(GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR) {
+		DWORD dwRetVal = 0;
+		PMIB_IPADDRTABLE pIPAddrTable;
+		DWORD dwSize = 0;
+#ifdef DEBUG
+		IN_ADDR IPAddr;
+#endif
+		int i;
+#ifdef DEBUG
+		printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop);
+#endif
+		pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE));
+		if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
+			free(pIPAddrTable);
+			pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize);
+		}
+		if(pIPAddrTable) {
+			dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
+#ifdef DEBUG
+			printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
+#endif
+			for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) {
+#ifdef DEBUG
+				printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex);
+				IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
+				printf("\tIP Address[%d]:     \t%s\n", i, inet_ntoa(IPAddr) );
+				IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
+				printf("\tSubnet Mask[%d]:    \t%s\n", i, inet_ntoa(IPAddr) );
+				IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
+				printf("\tBroadCast[%d]:      \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr);
+				printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize);
+				printf("\tType and State[%d]:", i);
+				printf("\n");
+#endif
+				if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) {
+					/* Set the address of this interface to be used */
+					struct in_addr mc_if;
+					memset(&mc_if, 0, sizeof(mc_if));
+					mc_if.s_addr = pIPAddrTable->table[i].dwAddr;
+					if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
+						PRINT_SOCKET_ERROR("setsockopt");
+					}
+					((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr;
+#ifndef DEBUG
+					break;
+#endif
+				}
+			}
+			free(pIPAddrTable);
+			pIPAddrTable = NULL;
+		}
+	}
+#endif
 
 #ifdef WIN32
 	if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
@@ -418,7 +543,10 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 	{
 		struct in_addr mc_if;
 		mc_if.s_addr = inet_addr(multicastif);
-    	sockudp_r.sin_addr.s_addr = mc_if.s_addr;
+		if(0/*ipv6*/) {
+		} else {
+			((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
+		}
 		if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
 		{
 			PRINT_SOCKET_ERROR("setsockopt");
@@ -426,13 +554,15 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 	}
 
 	/* Avant d'envoyer le paquet on bind pour recevoir la reponse */
-    if (bind(sudp, (struct sockaddr *)&sockudp_r, sizeof(struct sockaddr_in)) != 0)
+    if (bind(sudp, &sockudp_r, 0/*ipv6*/?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) != 0)
 	{
         PRINT_SOCKET_ERROR("bind");
 		closesocket(sudp);
 		return NULL;
     }
 
+	/* Calculating maximum response time in seconds */
+	mx = ((unsigned int)delay) / 1000u;
 	/* receiving SSDP response packet */
 	for(n = 0;;)
 	{
@@ -440,8 +570,9 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 	{
 		/* sending the SSDP M-SEARCH packet */
 		n = snprintf(bufr, sizeof(bufr),
-		             MSearchMsgFmt, deviceList[deviceIndex++]);
+		             MSearchMsgFmt, deviceList[deviceIndex++], mx);
 		/*printf("Sending %s", bufr);*/
+#if 0
 		n = sendto(sudp, bufr, n, 0,
 		           (struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));
 		if (n < 0) {
@@ -449,6 +580,31 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 			closesocket(sudp);
 			return devlist;
 		}
+#endif
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET
+		hints.ai_socktype = SOCK_DGRAM;
+		/*hints.ai_flags = */
+		if ((rv = getaddrinfo(UPNP_MCAST_ADDR, XSTR(PORT), &hints, &servinfo)) != 0) {
+#ifdef WIN32
+		    fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
+#else
+		    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
+#endif
+		    return devlist;
+		}
+		for(p = servinfo; p; p = p->ai_next) {
+			n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
+			if (n < 0) {
+				PRINT_SOCKET_ERROR("sendto");
+				continue;
+			}
+		}
+		freeaddrinfo(servinfo);
+		if(n < 0) {
+			closesocket(sudp);
+			return devlist;
+		}
 	}
 	/* Waiting for SSDP REPLY packet to M-SEARCH */
 	n = ReceiveData(sudp, bufr, sizeof(bufr), delay);
@@ -472,8 +628,21 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 		parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize);
 		if(st&&descURL)
 		{
-			/*printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
-			       stsize, st, urlsize, descURL); */
+#ifdef DEBUG
+			printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
+			       stsize, st, urlsize, descURL);
+#endif
+			for(tmp=devlist; tmp; tmp = tmp->pNext) {
+				if(memcmp(tmp->descURL, descURL, urlsize) == 0 &&
+				   tmp->descURL[urlsize] == '\0' &&
+				   memcmp(tmp->st, st, stsize) == 0 &&
+				   tmp->st[stsize] == '\0')
+					break;
+			}
+			/* at the exit of the loop above, tmp is null if
+			 * no duplicate device was found */
+			if(tmp)
+				continue;
 			tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
 			tmp->pNext = devlist;
 			tmp->descURL = tmp->buffer;
@@ -490,7 +659,7 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
 
 /* freeUPNPDevlist() should be used to
  * free the chained list returned by upnpDiscover() */
-void freeUPNPDevlist(struct UPNPDev * devlist)
+LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist)
 {
 	struct UPNPDev * next;
 	while(devlist)
@@ -526,7 +695,7 @@ url_cpy_or_cat(char * dst, const char * src, int n)
 
 /* Prepare the Urls for usage...
  */
-void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
+LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
                  const char * descURL)
 {
 	char * p;
@@ -536,9 +705,9 @@ void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
 		n1 = strlen(descURL);
 	n1 += 2;	/* 1 byte more for Null terminator, 1 byte for '/' if needed */
 	n2 = n1; n3 = n1;
-	n1 += strlen(data->scpdurl);
-	n2 += strlen(data->controlurl);
-	n3 += strlen(data->controlurl_CIF);
+	n1 += strlen(data->first.scpdurl);
+	n2 += strlen(data->first.controlurl);
+	n3 += strlen(data->CIF.controlurl);
 
 	urls->ipcondescURL = (char *)malloc(n1);
 	urls->controlURL = (char *)malloc(n2);
@@ -553,23 +722,23 @@ void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
 	strncpy(urls->controlURL, urls->ipcondescURL, n2);
 	strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
 	
-	url_cpy_or_cat(urls->ipcondescURL, data->scpdurl, n1);
+	url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
 
-	url_cpy_or_cat(urls->controlURL, data->controlurl, n2);
+	url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2);
 
-	url_cpy_or_cat(urls->controlURL_CIF, data->controlurl_CIF, n3);
+	url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
 
 #ifdef DEBUG
-	printf("urls->ipcondescURL='%s' %d n1=%d\n", urls->ipcondescURL,
-	       strlen(urls->ipcondescURL), n1);
-	printf("urls->controlURL='%s' %d n2=%d\n", urls->controlURL,
-	       strlen(urls->controlURL), n2);
-	printf("urls->controlURL_CIF='%s' %d n3=%d\n", urls->controlURL_CIF,
-	       strlen(urls->controlURL_CIF), n3);
+	printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL,
+	       (unsigned)strlen(urls->ipcondescURL), n1);
+	printf("urls->controlURL='%s' %u n2=%d\n", urls->controlURL,
+	       (unsigned)strlen(urls->controlURL), n2);
+	printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
+	       (unsigned)strlen(urls->controlURL_CIF), n3);
 #endif
 }
 
-void
+LIBSPEC void
 FreeUPNPUrls(struct UPNPUrls * urls)
 {
 	if(!urls)
@@ -586,11 +755,17 @@ FreeUPNPUrls(struct UPNPUrls * urls)
 int ReceiveData(int socket, char * data, int length, int timeout)
 {
     int n;
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
     struct pollfd fds[1]; /* for the poll */
-    fds[0].fd = socket;
-    fds[0].events = POLLIN;
-    n = poll(fds, 1, timeout);
+#ifdef MINIUPNPC_IGNORE_EINTR
+    do {
+#endif
+        fds[0].fd = socket;
+        fds[0].events = POLLIN;
+        n = poll(fds, 1, timeout);
+#ifdef MINIUPNPC_IGNORE_EINTR
+    } while(n < 0 && errno == EINTR);
+#endif
     if(n < 0)
     {
         PRINT_SOCKET_ERROR("poll");
@@ -607,7 +782,6 @@ int ReceiveData(int socket, char * data, int length, int timeout)
     FD_SET(socket, &socketSet);
     timeval.tv_sec = timeout / 1000;
     timeval.tv_usec = (timeout % 1000) * 1000;
-    /*n = select(0, &socketSet, NULL, NULL, &timeval);*/
     n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
     if(n < 0)
     {
@@ -633,7 +807,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
 	char status[64];
 	unsigned int uptime;
 	status[0] = '\0';
-	UPNP_GetStatusInfo(urls->controlURL, data->servicetype,
+	UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
 	                   status, &uptime, NULL);
 	if(0 == strcmp("Connected", status))
 	{
@@ -656,7 +830,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
  * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
  * free allocated memory.
  */
-int
+LIBSPEC int
 UPNP_GetValidIGD(struct UPNPDev * devlist,
                  struct UPNPUrls * urls,
 				 struct IGDdatas * data,
@@ -690,7 +864,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
 				parserootdesc(descXML, descXMLsize, data);
 				free(descXML);
 				descXML = NULL;
-				if(0==strcmp(data->servicetype_CIF,
+				if(0==strcmp(data->CIF.servicetype,
 				   "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
 				   || state >= 3 )
 				{
@@ -704,6 +878,25 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
 				  if((state >= 2) || UPNPIGD_IsConnected(urls, data))
 					return state;
 				  FreeUPNPUrls(urls);
+				  if(data->second.servicetype[0] != '\0') {
+#ifdef DEBUG
+				    printf("We tried %s, now we try %s !\n",
+				           data->first.servicetype, data->second.servicetype);
+#endif
+				    /* swaping WANPPPConnection and WANIPConnection ! */
+				    memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
+				    memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
+				    memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
+				    GetUPNPUrls(urls, data, dev->descURL);
+#ifdef DEBUG
+				    printf("UPNPIGD_IsConnected(%s) = %d\n",
+				       urls->controlURL,
+			           UPNPIGD_IsConnected(urls, data));
+#endif
+				    if((state >= 2) || UPNPIGD_IsConnected(urls, data))
+					  return state;
+				    FreeUPNPUrls(urls);
+				  }
 				}
 				memset(data, 0, sizeof(struct IGDdatas));
 			}
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.def b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.def
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/miniupnpc.def
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.def
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.h
similarity index 95%
rename from libportfwd/third-party/miniupnpc-20090605/miniupnpc.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.h
index bce314e82..2379ba14c 100644
--- a/libportfwd/third-party/miniupnpc-20090605/miniupnpc.h
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpc.h
@@ -1,4 +1,4 @@
-/* $Id: miniupnpc.h,v 1.18 2008/09/25 18:02:50 nanard Exp $ */
+/* $Id: miniupnpc.h,v 1.19 2009/10/10 19:15:35 nanard Exp $ */
 /* Project: miniupnp
  * http://miniupnp.free.fr/
  * Author: Thomas Bernard
@@ -102,6 +102,10 @@ LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
  * read or if we timed out. Returns negative if there was an error. */
 int ReceiveData(int socket, char * data, int length, int timeout);
 
+/* return 0 or 1 */
+LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpcmodule.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcmodule.c
similarity index 85%
rename from libportfwd/third-party/miniupnpc-20090605/miniupnpcmodule.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcmodule.c
index 121ff2052..c09e98261 100644
--- a/libportfwd/third-party/miniupnpc-20090605/miniupnpcmodule.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcmodule.c
@@ -1,8 +1,8 @@
-/* $Id: miniupnpcmodule.c,v 1.13 2009/04/17 20:59:42 nanard Exp $*/
+/* $Id: miniupnpcmodule.c,v 1.15 2010/06/09 10:23:01 nanard Exp $*/
 /* Project : miniupnp
  * Author : Thomas BERNARD
  * website : http://miniupnp.tuxfamily.org/
- * copyright (c) 2007 Thomas Bernard
+ * copyright (c) 2007-2009 Thomas Bernard
  * This software is subjet to the conditions detailed in the
  * provided LICENCE file. */
 #include <Python.h>
@@ -72,11 +72,13 @@ UPnP_discover(UPnPObject *self)
 	{
 		freeUPNPDevlist(self->devlist);
 		self->devlist = 0;
-	}
+	} 
+	Py_BEGIN_ALLOW_THREADS
 	self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
 	                             0/* multicast if*/,
 	                             0/*minissdpd socket*/,
 								 0/*sameport flag*/);
+	Py_END_ALLOW_THREADS
 	/* Py_RETURN_NONE ??? */
 	for(dev = self->devlist, i = 0; dev; dev = dev->pNext)
 		i++;
@@ -87,8 +89,12 @@ UPnP_discover(UPnPObject *self)
 static PyObject *
 UPnP_selectigd(UPnPObject *self)
 {
-	if(UPNP_GetValidIGD(self->devlist, &self->urls, &self->data,
-	                    self->lanaddr, sizeof(self->lanaddr)))
+	int r;
+Py_BEGIN_ALLOW_THREADS
+	r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data,
+	                     self->lanaddr, sizeof(self->lanaddr));
+Py_END_ALLOW_THREADS
+	if(r)
 	{
 		return Py_BuildValue("s", self->urls.controlURL);
 	}
@@ -103,33 +109,45 @@ UPnP_selectigd(UPnPObject *self)
 static PyObject *
 UPnP_totalbytesent(UPnPObject *self)
 {
-	return Py_BuildValue("I",
-	           UPNP_GetTotalBytesSent(self->urls.controlURL_CIF,
-			                          self->data.servicetype_CIF));
+	UNSIGNED_INTEGER i;
+Py_BEGIN_ALLOW_THREADS
+	i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF,
+	                           self->data.CIF.servicetype);
+Py_END_ALLOW_THREADS
+	return Py_BuildValue("I", i);
 }
 
 static PyObject *
 UPnP_totalbytereceived(UPnPObject *self)
 {
-	return Py_BuildValue("I",
-	           UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF,
-			                          self->data.servicetype_CIF));
+	UNSIGNED_INTEGER i;
+Py_BEGIN_ALLOW_THREADS
+	i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF,
+		                           self->data.CIF.servicetype);
+Py_END_ALLOW_THREADS
+	return Py_BuildValue("I", i);
 }
 
 static PyObject *
 UPnP_totalpacketsent(UPnPObject *self)
 {
-	return Py_BuildValue("I",
-	           UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF,
-			                          self->data.servicetype_CIF));
+	UNSIGNED_INTEGER i;
+Py_BEGIN_ALLOW_THREADS
+	i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF,
+		                         self->data.CIF.servicetype);
+Py_END_ALLOW_THREADS
+	return Py_BuildValue("I", i);
 }
 
 static PyObject *
 UPnP_totalpacketreceived(UPnPObject *self)
 {
-	return Py_BuildValue("I",
-	           UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF,
-			                          self->data.servicetype_CIF));
+	UNSIGNED_INTEGER i;
+Py_BEGIN_ALLOW_THREADS
+	i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF,
+		                          self->data.CIF.servicetype);
+Py_END_ALLOW_THREADS
+	return Py_BuildValue("I", i);
 }
 
 static PyObject *
@@ -141,8 +159,10 @@ UPnP_statusinfo(UPnPObject *self)
 	int r;
 	status[0] = '\0';
 	lastconnerror[0] = '\0';
-	r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.servicetype,
+Py_BEGIN_ALLOW_THREADS
+	r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype,
 	                   status, &uptime, lastconnerror);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS) {
 		return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror);
 	} else {
@@ -158,9 +178,11 @@ UPnP_connectiontype(UPnPObject *self)
 	char connectionType[64];
 	int r;
 	connectionType[0] = '\0';
+Py_BEGIN_ALLOW_THREADS
 	r = UPNP_GetConnectionTypeInfo(self->urls.controlURL,
-	                               self->data.servicetype,
+	                               self->data.first.servicetype,
 	                               connectionType);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS) {
 		return Py_BuildValue("s", connectionType);
 	} else {
@@ -176,9 +198,11 @@ UPnP_externalipaddress(UPnPObject *self)
 	char externalIPAddress[16];
 	int r;
 	externalIPAddress[0] = '\0';
+Py_BEGIN_ALLOW_THREADS
 	r = UPNP_GetExternalIPAddress(self->urls.controlURL,
-	                              self->data.servicetype,
+	                              self->data.first.servicetype,
 	                              externalIPAddress);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS) {
 		return Py_BuildValue("s", externalIPAddress);
 	} else {
@@ -206,10 +230,12 @@ UPnP_addportmapping(UPnPObject *self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto,
 	                                     &host, &iPort, &desc, &remoteHost))
         return NULL;
+Py_BEGIN_ALLOW_THREADS
 	sprintf(extPort, "%hu", ePort);
 	sprintf(inPort, "%hu", iPort);
-	r = UPNP_AddPortMapping(self->urls.controlURL, self->data.servicetype,
+	r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype,
 	                        extPort, inPort, host, desc, proto, remoteHost);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS)
 	{
 		Py_RETURN_TRUE;
@@ -237,9 +263,11 @@ UPnP_deleteportmapping(UPnPObject *self, PyObject *args)
 	int r;
 	if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
 		return NULL;
+Py_BEGIN_ALLOW_THREADS
 	sprintf(extPort, "%hu", ePort);
-	r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.servicetype,
+	r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype,
 	                           extPort, proto, remoteHost);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS) {
 		Py_RETURN_TRUE;
 	} else {
@@ -254,9 +282,11 @@ UPnP_getportmappingnumberofentries(UPnPObject *self)
 {
 	unsigned int n = 0;
 	int r;
+Py_BEGIN_ALLOW_THREADS
 	r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL,
-	                                   self->data.servicetype,
+	                                   self->data.first.servicetype,
 									   &n);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS) {
 		return Py_BuildValue("I", n);
 	} else {
@@ -279,11 +309,13 @@ UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
 	unsigned short iPort;
 	if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto))
 		return NULL;
+Py_BEGIN_ALLOW_THREADS
 	sprintf(extPort, "%hu", ePort);
 	UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
-	                                 self->data.servicetype,
+	                                 self->data.first.servicetype,
 									 extPort, proto,
 									 intClient, intPort);
+Py_END_ALLOW_THREADS
 	if(intClient[0])
 	{
 		iPort = (unsigned short)atoi(intPort);
@@ -314,16 +346,18 @@ UPnP_getgenericportmapping(UPnPObject *self, PyObject *args)
 	unsigned int dur;
 	if(!PyArg_ParseTuple(args, "i", &i))
 		return NULL;
+Py_BEGIN_ALLOW_THREADS
 	snprintf(index, sizeof(index), "%d", i);
 	rHost[0] = '\0'; enabled[0] = '\0';
 	duration[0] = '\0'; desc[0] = '\0';
 	extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
 	r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL,
-	                                    self->data.servicetype,
+	                                    self->data.first.servicetype,
 										index,
 										extPort, intClient, intPort,
 										protocol, desc, enabled, rHost,
 										duration);
+Py_END_ALLOW_THREADS
 	if(r==UPNPCOMMAND_SUCCESS)
 	{
 		ePort = (unsigned short)atoi(extPort);
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h
new file mode 100644
index 000000000..8cbb4ec16
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h
@@ -0,0 +1,15 @@
+/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
+/* Project: miniupnp
+ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
+ * Author: Thomas Bernard
+ * Copyright (c) 2005-2009 Thomas Bernard
+ * This software is subjects to the conditions detailed
+ * in the LICENCE file provided within this distribution */
+#ifndef __MINIUPNPCSTRINGS_H__
+#define __MINIUPNPCSTRINGS_H__
+
+#define OS_STRING "Linux/2.6.35-ARCH"
+#define MINIUPNPC_VERSION_STRING "1.4"
+
+#endif
+
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniupnpcstrings.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h.in
similarity index 70%
rename from libportfwd/third-party/miniupnpc-20090605/miniupnpcstrings.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h.in
index 8f1b6c26d..8ab3f29f7 100644
--- a/libportfwd/third-party/miniupnpc-20090605/miniupnpcstrings.h
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniupnpcstrings.h.in
@@ -1,4 +1,4 @@
-/* $Id: miniupnpcstrings.h,v 1.3 2009/06/04 09:05:56 nanard Exp $ */
+/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
 /* Project: miniupnp
  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
  * Author: Thomas Bernard
@@ -8,8 +8,8 @@
 #ifndef __MINIUPNPCSTRINGS_H__
 #define __MINIUPNPCSTRINGS_H__
 
-#define OS_STRING "OpenBSD/4.3"
-#define MINIUPNPC_VERSION_STRING "1.3"
+#define OS_STRING "OS/version"
+#define MINIUPNPC_VERSION_STRING "1.4"
 
 #endif
 
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniwget.c b/libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.c
similarity index 60%
rename from libportfwd/third-party/miniupnpc-20090605/miniwget.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.c
index 0a026cbb1..aa5ee26ec 100644
--- a/libportfwd/third-party/miniupnpc-20090605/miniwget.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.c
@@ -1,84 +1,79 @@
-/* $Id: miniwget.c,v 1.22 2009/02/28 10:36:35 nanard Exp $ */
+/* $Id: miniwget.c,v 1.37 2010/04/12 20:39:42 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
+ * Copyright (c) 2005-2010 Thomas Bernard
  * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
+ * LICENCE file provided in this distribution. */
+ 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "miniupnpc.h"
 #ifdef WIN32
 #include <winsock2.h>
+#include <ws2tcpip.h>
 #include <io.h>
 #define MAXHOSTNAMELEN 64
 #define MIN(x,y) (((x)<(y))?(x):(y))
 #define snprintf _snprintf
-#define herror
 #define socklen_t int
-#else
+#else /* #ifdef WIN32 */
 #include <unistd.h>
 #include <sys/param.h>
+#if defined(__amigaos__) && !defined(__amigaos4__)
+#define socklen_t int
+#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
+#include <sys/select.h>
+#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
 #include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netdb.h>
 #define closesocket close
-#endif
+/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
+ * during the connect() call */
+#define MINIUPNPC_IGNORE_EINTR
+#endif /* #else WIN32 */
 #if defined(__sun) || defined(sun)
 #define MIN(x,y) (((x)<(y))?(x):(y))
 #endif
 
 #include "miniupnpcstrings.h"
+#include "miniwget.h"
+#include "connecthostport.h"
 
-/* miniwget2() :
- * */
+/* miniwget3() :
+ * do all the work.
+ * Return NULL if something failed. */
 static void *
-miniwget2(const char * url, const char * host,
+miniwget3(const char * url, const char * host,
 		  unsigned short port, const char * path,
-		  int * size, char * addr_str, int addr_str_len)
+		  int * size, char * addr_str, int addr_str_len, const char * httpversion)
 {
 	char buf[2048];
     int s;
-	struct sockaddr_in dest;
-	struct hostent *hp;
+	int n;
+	int len;
+	int sent;
+
 	*size = 0;
-	hp = gethostbyname(host);
-	if(hp==NULL)
-	{
-		herror(host);
-		return NULL;
-	}
-	/*  memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length);  */
-	memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
-	memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
-	s = socket(PF_INET, SOCK_STREAM, 0);
+	s = connecthostport(host, port);
 	if(s < 0)
-	{
-		perror("socket");
 		return NULL;
-	}
-	dest.sin_family = AF_INET;
-	dest.sin_port = htons(port);
-	if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in))<0)
-	{
-		perror("connect");
-		closesocket(s);
-		return NULL;
-	}
 
 	/* get address for caller ! */
 	if(addr_str)
 	{
-		struct sockaddr_in saddr;
-		socklen_t len;
+		struct sockaddr saddr;
+		socklen_t saddrlen;
 
-		len = sizeof(saddr);
-		getsockname(s, (struct sockaddr *)&saddr, &len);
-#ifndef WIN32
-		inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
-#else
+		saddrlen = sizeof(saddr);
+		if(getsockname(s, &saddr, &saddrlen) < 0)
+		{
+			perror("getsockname");
+		}
+		else
+		{
+#if defined(__amigaos__) && !defined(__amigaos4__)
 	/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
      * But his function make a string with the port :  nn.nn.nn.nn:port */
 /*		if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
@@ -86,25 +81,56 @@ miniwget2(const char * url, const char * host,
 		{
 		    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
 		}*/
-		strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
+			strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
+#else
+			/*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
+			n = getnameinfo(&saddr, saddrlen,
+			                addr_str, addr_str_len,
+			                NULL, 0,
+			                NI_NUMERICHOST | NI_NUMERICSERV);
+			if(n != 0) {
+#ifdef WIN32
+				fprintf(stderr, "getnameinfo() failed : %d\n", n);
+#else
+				fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
 #endif
+			}
+#endif
+		}
 #ifdef DEBUG
 		printf("address miniwget : %s\n", addr_str);
 #endif
 	}
 
-	snprintf(buf, sizeof(buf),
-                 "GET %s HTTP/1.1\r\n"
+	len = snprintf(buf, sizeof(buf),
+                 "GET %s HTTP/%s\r\n"
 			     "Host: %s:%d\r\n"
 				 "Connection: Close\r\n"
 				 "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
 
 				 "\r\n",
-		    path, host, port);
-	/*write(s, buf, strlen(buf));*/
-	send(s, buf, strlen(buf), 0);
+			   path, httpversion, host, port);
+	sent = 0;
+	/* sending the HTTP request */
+	while(sent < len)
 	{
-		int n, headers=1;
+		n = send(s, buf+sent, len-sent, 0);
+		if(n < 0)
+		{
+			perror("send");
+			closesocket(s);
+			return NULL;
+		}
+		else
+		{
+			sent += n;
+		}
+	}
+	{
+		/* TODO : in order to support HTTP/1.1, chunked transfer encoding
+		 *        must be supported. That means parsing of headers must be
+		 *        added.                                                   */
+		int headers=1;
 		char * respbuffer = NULL;
 		int allreadyread = 0;
 		/*while((n = recv(s, buf, 2048, 0)) > 0)*/
@@ -115,12 +141,14 @@ miniwget2(const char * url, const char * host,
 				int i=0;
 				while(i<n-3)
 				{
+					/* searching for the end of the HTTP headers */
 					if(buf[i]=='\r' && buf[i+1]=='\n'
 					   && buf[i+2]=='\r' && buf[i+3]=='\n')
 					{
 						headers = 0;	/* end */
 						if(i<n-4)
 						{
+							/* Copy the content into respbuffet */
 							respbuffer = (char *)realloc((void *)respbuffer, 
 														 allreadyread+(n-i-4));
 							memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
@@ -148,6 +176,30 @@ miniwget2(const char * url, const char * host,
 	}
 }
 
+/* miniwget2() :
+ * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
+static void *
+miniwget2(const char * url, const char * host,
+		  unsigned short port, const char * path,
+		  int * size, char * addr_str, int addr_str_len)
+{
+	char * respbuffer;
+
+	respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
+	if (*size == 0)
+	{
+#ifdef DEBUG
+		printf("Retrying with HTTP/1.1\n");
+#endif
+		free(respbuffer);
+		respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
+	}
+	return respbuffer;
+}
+
+
+
+
 /* parseURL()
  * arguments :
  *   url :		source string not modified
diff --git a/libportfwd/third-party/miniupnpc-20090605/miniwget.h b/libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/miniwget.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/miniwget.h
diff --git a/libportfwd/third-party/miniupnpc-20090605/minixml.c b/libportfwd/third-party/miniupnpc-1.4.20100609/minixml.c
similarity index 96%
rename from libportfwd/third-party/miniupnpc-20090605/minixml.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minixml.c
index dce690e2e..83c6acd97 100644
--- a/libportfwd/third-party/miniupnpc-20090605/minixml.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/minixml.c
@@ -1,10 +1,10 @@
-/* $Id: minixml.c,v 1.6 2007/05/15 18:14:08 nanard Exp $ */
+/* $Id: minixml.c,v 1.7 2009/10/10 19:15:35 nanard Exp $ */
 /* minixml.c : the minimum size a xml parser can be ! */
 /* Project : miniupnp
  * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
  * Author : Thomas Bernard
 
-Copyright (c) 2005-2007, Thomas BERNARD 
+Copyright (c) 2005-2009, Thomas BERNARD 
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
 /* parseatt : used to parse the argument list
  * return 0 (false) in case of success and -1 (true) if the end
  * of the xmlbuffer is reached. */
-int parseatt(struct xmlparser * p)
+static int parseatt(struct xmlparser * p)
 {
 	const char * attname;
 	int attnamelen;
@@ -106,7 +106,7 @@ int parseatt(struct xmlparser * p)
 
 /* parseelt parse the xml stream and
  * call the callback functions when needed... */
-void parseelt(struct xmlparser * p)
+static void parseelt(struct xmlparser * p)
 {
 	int i;
 	const char * elementname;
diff --git a/libportfwd/third-party/miniupnpc-20090605/minixml.h b/libportfwd/third-party/miniupnpc-1.4.20100609/minixml.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/minixml.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minixml.h
diff --git a/libportfwd/third-party/miniupnpc-20090605/minixmlvalid.c b/libportfwd/third-party/miniupnpc-1.4.20100609/minixmlvalid.c
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/minixmlvalid.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/minixmlvalid.c
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.sln b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.sln
new file mode 100644
index 000000000..b3da1919e
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.sln
@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "miniupnpc.vcproj", "{D28CE435-CB33-4BAE-8A52-C6EF915956F5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upnpc-static", "upnpc-static.vcproj", "{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}"
+	ProjectSection(ProjectDependencies) = postProject
+		{D28CE435-CB33-4BAE-8A52-C6EF915956F5} = {D28CE435-CB33-4BAE-8A52-C6EF915956F5}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.Build.0 = Debug|Win32
+		{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.ActiveCfg = Release|Win32
+		{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.Build.0 = Release|Win32
+		{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.Build.0 = Debug|Win32
+		{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.ActiveCfg = Release|Win32
+		{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.vcproj b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.vcproj
new file mode 100644
index 000000000..a2c433ea0
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/miniupnpc.vcproj
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="miniupnpc"
+	ProjectGUID="{D28CE435-CB33-4BAE-8A52-C6EF915956F5}"
+	RootNamespace="miniupnpc"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;WIN32;STATICLIB;DEBUG"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;WIN32;STATICLIB"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Fichiers sources"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\connecthostport.c"
+				>
+			</File>
+			<File
+				RelativePath="..\igd_desc_parse.c"
+				>
+			</File>
+			<File
+				RelativePath="..\minisoap.c"
+				>
+			</File>
+			<File
+				RelativePath="..\miniupnpc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\miniwget.c"
+				>
+			</File>
+			<File
+				RelativePath="..\minixml.c"
+				>
+			</File>
+			<File
+				RelativePath="..\upnpcommands.c"
+				>
+			</File>
+			<File
+				RelativePath="..\upnperrors.c"
+				>
+			</File>
+			<File
+				RelativePath="..\upnpreplyparse.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Fichiers d&apos;en-t�te"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\bsdqueue.h"
+				>
+			</File>
+			<File
+				RelativePath="..\connecthostport.h"
+				>
+			</File>
+			<File
+				RelativePath="..\declspec.h"
+				>
+			</File>
+			<File
+				RelativePath="..\igd_desc_parse.h"
+				>
+			</File>
+			<File
+				RelativePath="..\minisoap.h"
+				>
+			</File>
+			<File
+				RelativePath="..\miniupnpc.h"
+				>
+			</File>
+			<File
+				RelativePath="..\miniupnpcstrings.h"
+				>
+			</File>
+			<File
+				RelativePath="..\miniwget.h"
+				>
+			</File>
+			<File
+				RelativePath="..\minixml.h"
+				>
+			</File>
+			<File
+				RelativePath="..\upnpcommands.h"
+				>
+			</File>
+			<File
+				RelativePath="..\upnperrors.h"
+				>
+			</File>
+			<File
+				RelativePath="..\upnpreplyparse.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Fichiers de ressources"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj
new file mode 100644
index 000000000..294613877
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/msvc/upnpc-static.vcproj
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="upnpc-static"
+	ProjectGUID="{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}"
+	RootNamespace="upnpcstatic"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;STATICLIB;DEBUG;_CRT_SECURE_NO_WARNINGS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib IPHlpApi.Lib Debug\miniupnpc.lib"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;STATICLIB"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib IPHlpApi.Lib Release\miniupnpc.lib"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Fichiers sources"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\upnpc.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Fichiers d&apos;en-t�te"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Fichiers de ressources"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/libportfwd/third-party/miniupnpc-20090605/pymoduletest.py b/libportfwd/third-party/miniupnpc-1.4.20100609/pymoduletest.py
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/pymoduletest.py
rename to libportfwd/third-party/miniupnpc-1.4.20100609/pymoduletest.py
diff --git a/libportfwd/third-party/miniupnpc-20090605/setup.py b/libportfwd/third-party/miniupnpc-1.4.20100609/setup.py
similarity index 73%
rename from libportfwd/third-party/miniupnpc-20090605/setup.py
rename to libportfwd/third-party/miniupnpc-1.4.20100609/setup.py
index 8ecb5f392..119ec4bec 100644
--- a/libportfwd/third-party/miniupnpc-20090605/setup.py
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/setup.py
@@ -1,13 +1,13 @@
 #! /usr/bin/python
-# $Id: setup.py,v 1.3 2009/04/17 20:59:42 nanard Exp $
-# the MiniUPnP Project (c) 2007 Thomas Bernard
+# $Id: setup.py,v 1.5 2009/10/30 09:18:18 nanard Exp $
+# the MiniUPnP Project (c) 2007-2009 Thomas Bernard
 # http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
 #
 # python script to build the miniupnpc module under unix
 #
 # replace libminiupnpc.a by libminiupnpc.so for shared library usage
 from distutils.core import setup, Extension
-setup(name="miniupnpc", version="1.3",
+setup(name="miniupnpc", version="1.4",
       ext_modules=[
 	         Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
 			           extra_objects=["libminiupnpc.a"])
diff --git a/libportfwd/third-party/miniupnpc-20090605/setupmingw32.py b/libportfwd/third-party/miniupnpc-1.4.20100609/setupmingw32.py
old mode 100755
new mode 100644
similarity index 70%
rename from libportfwd/third-party/miniupnpc-20090605/setupmingw32.py
rename to libportfwd/third-party/miniupnpc-1.4.20100609/setupmingw32.py
index 62433e4ac..6e612453d
--- a/libportfwd/third-party/miniupnpc-20090605/setupmingw32.py
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/setupmingw32.py
@@ -1,12 +1,12 @@
 #! /usr/bin/python
-# $Id: setupmingw32.py,v 1.1 2007/06/12 23:04:13 nanard Exp $
-# the MiniUPnP Project (c) 2007 Thomas Bernard
+# $Id: setupmingw32.py,v 1.3 2009/10/30 09:18:18 nanard Exp $
+# the MiniUPnP Project (c) 2007-2009 Thomas Bernard
 # http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
 #
 # python script to build the miniupnpc module under unix
 #
 from distutils.core import setup, Extension
-setup(name="miniupnpc", version="1.0-RC6",
+setup(name="miniupnpc", version="1.4",
       ext_modules=[
 	         Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
 	                   libraries=["ws2_32"],
diff --git a/libportfwd/third-party/miniupnpc-20090605/testigddescparse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testigddescparse.c
similarity index 75%
rename from libportfwd/third-party/miniupnpc-20090605/testigddescparse.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/testigddescparse.c
index 527f5e111..1b0cde90e 100644
--- a/libportfwd/third-party/miniupnpc-20090605/testigddescparse.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/testigddescparse.c
@@ -1,8 +1,8 @@
-/* $Id: testigddescparse.c,v 1.1 2008/04/23 11:53:45 nanard Exp $ */
+/* $Id: testigddescparse.c,v 1.2 2009/12/03 13:50:06 nanard Exp $ */
 /* Project : miniupnp
  * http://miniupnp.free.fr/
  * Author : Thomas Bernard
- * Copyright (c) 2008 Thomas Bernard
+ * Copyright (c) 2008-2009 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  * */
@@ -11,11 +11,13 @@
 #include <string.h>
 #include "igd_desc_parse.h"
 #include "minixml.h"
+#include "miniupnpc.h"
 
 int test_igd_desc_parse(char * buffer, int len)
 {
 	struct IGDdatas igd;
 	struct xmlparser parser;
+	struct UPNPUrls urls;
 	memset(&igd, 0, sizeof(struct IGDdatas));
 	memset(&parser, 0, sizeof(struct xmlparser));
 	parser.xmlstart = buffer;
@@ -26,6 +28,11 @@ int test_igd_desc_parse(char * buffer, int len)
 	parser.datafunc = IGDdata; 
 	parsexml(&parser);
 	printIGD(&igd);
+	GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml");
+	printf("ipcondescURL='%s'\n", urls.ipcondescURL);
+	printf("controlURL='%s'\n", urls.controlURL);
+	printf("controlURL_CIF='%s'\n", urls.controlURL_CIF);
+	FreeUPNPUrls(&urls);
 	return 0;
 }
 
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c
new file mode 100644
index 000000000..0624e5adf
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/testminiwget.c
@@ -0,0 +1,45 @@
+/* $Id: testminiwget.c,v 1.1 2009/12/03 18:44:32 nanard Exp $ */
+/* Project : miniupnp
+ * Author : Thomas Bernard
+ * Copyright (c) 2005-2009 Thomas Bernard
+ * This software is subject to the conditions detailed in the
+ * LICENCE file provided in this distribution.
+ * */
+#include <stdio.h>
+#include <stdlib.h>
+#include "miniwget.h"
+
+int main(int argc, char * * argv)
+{
+	void * data;
+	int size, writtensize;
+	FILE *f;
+	if(argc < 3) {
+		fprintf(stderr, "Usage:\t%s url file\n", argv[0]);
+		fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]);
+		return 1;
+	}
+	data = miniwget(argv[1], &size);
+	if(!data) {
+		fprintf(stderr, "Error fetching %s\n", argv[1]);
+		return 1;
+	}
+	printf("got %d bytes\n", size);
+	f = fopen(argv[2], "wb");
+	if(!f) {
+		fprintf(stderr, "Cannot open file %s for writing\n", argv[2]);
+		free(data);
+		return 1;
+	}
+	writtensize = fwrite(data, 1, size, f);
+	if(writtensize != size) {
+		fprintf(stderr, "Could only write %d bytes out of %d to %s\n",
+		        writtensize, size, argv[2]);
+	} else {
+		printf("%d bytes written to %s\n", writtensize, argv[2]);
+	}
+	fclose(f);
+	free(data);
+	return 0;
+}
+
diff --git a/libportfwd/third-party/miniupnpc-20090605/testminixml.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testminixml.c
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/testminixml.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/testminixml.c
diff --git a/libportfwd/third-party/miniupnpc-20090605/testupnpigd.py b/libportfwd/third-party/miniupnpc-1.4.20100609/testupnpigd.py
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/testupnpigd.py
rename to libportfwd/third-party/miniupnpc-1.4.20100609/testupnpigd.py
diff --git a/libportfwd/third-party/miniupnpc-20090605/testupnpreplyparse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/testupnpreplyparse.c
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/testupnpreplyparse.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/testupnpreplyparse.c
diff --git a/libportfwd/third-party/miniupnpc-20090605/updateminiupnpcstrings.sh b/libportfwd/third-party/miniupnpc-1.4.20100609/updateminiupnpcstrings.sh
similarity index 56%
rename from libportfwd/third-party/miniupnpc-20090605/updateminiupnpcstrings.sh
rename to libportfwd/third-party/miniupnpc-1.4.20100609/updateminiupnpcstrings.sh
index f7b95a560..32fbf55ab 100755
--- a/libportfwd/third-party/miniupnpc-20090605/updateminiupnpcstrings.sh
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/updateminiupnpcstrings.sh
@@ -1,7 +1,10 @@
 #! /bin/sh
-# $Id: updateminiupnpcstrings.sh,v 1.2 2009/06/04 09:13:53 nanard Exp $
+# $Id: updateminiupnpcstrings.sh,v 1.6 2009/12/07 11:29:57 nanard Exp $
+# project miniupnp : http://miniupnp.free.fr/
+# (c) 2009 Thomas Bernard
 
 FILE=miniupnpcstrings.h
+TEMPLATE_FILE=${FILE}.in
 
 # detecting the OS name and version
 OS_NAME=`uname -s`
@@ -12,7 +15,7 @@ if [ -f /etc/debian_version ]; then
 fi
 # use lsb_release (Linux Standard Base) when available
 LSB_RELEASE=`which lsb_release`
-if [ 0 -eq $? ]; then
+if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then
 	OS_NAME=`${LSB_RELEASE} -i -s`
 	OS_VERSION=`${LSB_RELEASE} -r -s`
 	case $OS_NAME in
@@ -25,12 +28,18 @@ if [ 0 -eq $? ]; then
 	esac
 fi
 
+# on AmigaOS 3, uname -r returns "unknown", so we use uname -v
+if [ "$OS_NAME" = "AmigaOS" ]; then
+	if [ "$OS_VERSION" = "unknown" ]; then
+		OS_VERSION=`uname -v`
+	fi
+fi
+
 echo "Detected OS [$OS_NAME] version [$OS_VERSION]"
 
-EXPR="s/OS_STRING \".*\"/OS_STRING \"${OS_NAME}\/${OS_VERSION}\"/"
+EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|"
 #echo $EXPR
-echo "Backuping $FILE to $FILE.bak."
-cp $FILE $FILE.bak
+test -f ${FILE}.in
 echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE."
-cat $FILE.bak | sed -e "$EXPR" > $FILE
+sed -e "$EXPR" < $TEMPLATE_FILE > $FILE
 
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnpc.c b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpc.c
similarity index 85%
rename from libportfwd/third-party/miniupnpc-20090605/upnpc.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnpc.c
index 2c5debe31..f89e8779a 100644
--- a/libportfwd/third-party/miniupnpc-20090605/upnpc.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpc.c
@@ -1,13 +1,14 @@
-/* $Id: upnpc.c,v 1.65 2008/10/14 18:05:27 nanard Exp $ */
+/* $Id: upnpc.c,v 1.72 2010/05/29 09:21:12 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2005-2008 Thomas Bernard
+ * Copyright (c) 2005-2010 Thomas Bernard
  * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
+ * LICENCE file provided in this distribution. */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #ifdef WIN32
 #include <winsock2.h>
 #define snprintf _snprintf
@@ -46,23 +47,27 @@ static void DisplayInfos(struct UPNPUrls * urls,
 	char lastconnerr[64];
 	unsigned int uptime;
 	unsigned int brUp, brDown;
+	time_t timenow, timestarted;
 	int r;
 	UPNP_GetConnectionTypeInfo(urls->controlURL,
-	                           data->servicetype,
+	                           data->first.servicetype,
 							   connectionType);
 	if(connectionType[0])
 		printf("Connection Type : %s\n", connectionType);
 	else
 		printf("GetConnectionTypeInfo failed.\n");
-	UPNP_GetStatusInfo(urls->controlURL, data->servicetype,
+	UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
 	                   status, &uptime, lastconnerr);
-	printf("Status : %s, uptime=%u, LastConnectionError : %s\n",
+	printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
 	       status, uptime, lastconnerr);
-	UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->servicetype_CIF,
+	timenow = time(NULL);
+	timestarted = timenow - uptime;
+	printf("  Time started : %s", ctime(&timestarted));
+	UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
 			&brDown, &brUp);
 	printf("MaxBitRateDown : %u bps   MaxBitRateUp %u bps\n", brDown, brUp);
 	r = UPNP_GetExternalIPAddress(urls->controlURL,
-	                          data->servicetype,
+	                          data->first.servicetype,
 							  externalIPAddress);
 	if(r != UPNPCOMMAND_SUCCESS)
 		printf("GetExternalIPAddress() returned %d\n", r);
@@ -77,10 +82,10 @@ static void GetConnectionStatus(struct UPNPUrls * urls,
 {
 	unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
 	DisplayInfos(urls, data);
-	bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->servicetype_CIF);
-	bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->servicetype_CIF);
-	packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->servicetype_CIF);
-	packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->servicetype_CIF);
+	bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
+	bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
+	packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
+	packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
 	printf("Bytes:   Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
 	printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
 }
@@ -107,7 +112,8 @@ static void ListRedirections(struct UPNPUrls * urls,
 		rHost[0] = '\0'; enabled[0] = '\0';
 		duration[0] = '\0'; desc[0] = '\0';
 		extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
-		r = UPNP_GetGenericPortMappingEntry(urls->controlURL, data->servicetype,
+		r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
+		                               data->first.servicetype,
 		                               index,
 		                               extPort, intClient, intPort,
 									   protocol, desc, enabled,
@@ -160,25 +166,26 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
 	}
 	
 	UPNP_GetExternalIPAddress(urls->controlURL,
-	                          data->servicetype,
+	                          data->first.servicetype,
 							  externalIPAddress);
 	if(externalIPAddress[0])
 		printf("ExternalIPAddress = %s\n", externalIPAddress);
 	else
 		printf("GetExternalIPAddress failed.\n");
 	
-	r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
+	r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
 	                        eport, iport, iaddr, 0, proto, 0);
 	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("AddPortMapping(%s, %s, %s) failed with code %d\n",
-		       eport, iport, iaddr, r);
+		printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
+		       eport, iport, iaddr, r, strupnperror(r));
 
 	r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
-	                                 data->servicetype,
+	                                 data->first.servicetype,
     	                             eport, proto,
 									 intClient, intPort);
 	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("GetSpecificPortMappingEntry() failed with code %d\n", r);
+		printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
+		       r, strupnperror(r));
 	
 	if(intClient[0]) {
 		printf("InternalIP:Port = %s:%s\n", intClient, intPort);
@@ -205,7 +212,7 @@ RemoveRedirect(struct UPNPUrls * urls,
 		fprintf(stderr, "protocol invalid\n");
 		return;
 	}
-	r = UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto, 0);
+	r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0);
 	printf("UPNP_DeletePortMapping() returned : %d\n", r);
 }
 
@@ -217,11 +224,12 @@ int main(int argc, char ** argv)
 	char ** commandargv = 0;
 	int commandargc = 0;
 	struct UPNPDev * devlist = 0;
-	char lanaddr[16];	/* my ip address on the LAN */
+	char lanaddr[64];	/* my ip address on the LAN */
 	int i;
 	const char * rootdescurl = 0;
 	const char * multicastif = 0;
 	const char * minissdpdpath = 0;
+	int retcode = 0;
 
 #ifdef WIN32
 	WSADATA wsaData;
@@ -232,7 +240,7 @@ int main(int argc, char ** argv)
 		return -1;
 	}
 #endif
-    printf("upnpc : miniupnpc library test client. (c) 2006-2008 Thomas Bernard\n");
+    printf("upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard\n");
     printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
 	       "for more information.\n");
 	/* command line processing */
@@ -266,7 +274,7 @@ int main(int argc, char ** argv)
 	   || (command == 'r' && argc<2))
 	{
 		fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol\n\t\tAdd port redirection\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -d external_port protocol\n\t\tDelete port redirection\n", argv[0]);
+		fprintf(stderr, "       \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
 		fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
 		fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
 		fprintf(stderr, "       \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
@@ -336,7 +344,10 @@ int main(int argc, char ** argv)
 				                   commandargv[2], commandargv[3]);
 				break;
 			case 'd':
-				RemoveRedirect(&urls, &data, commandargv[0], commandargv[1]);
+				for(i=0; i<commandargc; i+=2)
+				{
+					RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
+				}
 				break;
 			case 's':
 				GetConnectionStatus(&urls, &data);
@@ -352,6 +363,7 @@ int main(int argc, char ** argv)
 				break;
 			default:
 				fprintf(stderr, "Unknown switch -%c\n", command);
+				retcode = 1;
 			}
 
 			FreeUPNPUrls(&urls);
@@ -359,16 +371,15 @@ int main(int argc, char ** argv)
 		else
 		{
 			fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
+			retcode = 1;
 		}
 		freeUPNPDevlist(devlist); devlist = 0;
 	}
 	else
 	{
 		fprintf(stderr, "No IGD UPnP Device found on the network !\n");
+		retcode = 1;
 	}
-
-	/*puts("************* HOP ***************");*/
-
-	return 0;
+	return retcode;
 }
 
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnpcommands.c b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpcommands.c
similarity index 79%
rename from libportfwd/third-party/miniupnpc-20090605/upnpcommands.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnpcommands.c
index e9842b1d6..20e48d819 100644
--- a/libportfwd/third-party/miniupnpc-20090605/upnpcommands.c
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpcommands.c
@@ -1,7 +1,7 @@
-/* $Id: upnpcommands.c,v 1.24 2009/04/17 21:21:19 nanard Exp $ */
+/* $Id: upnpcommands.c,v 1.26 2010/06/09 10:59:09 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2005-2009 Thomas Bernard
+ * Copyright (c) 2005-2010 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  * */
@@ -19,7 +19,7 @@ my_atoui(const char * s)
 
 /*
  * */
-UNSIGNED_INTEGER
+LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalBytesSent(const char * controlURL,
 					const char * servicetype)
 {
@@ -28,7 +28,9 @@ UPNP_GetTotalBytesSent(const char * controlURL,
 	int bufsize = 4096;
 	unsigned int r = 0;
 	char * p;
-	simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*DisplayNameValueList(buffer, bufsize);*/
 	p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
@@ -39,7 +41,7 @@ UPNP_GetTotalBytesSent(const char * controlURL,
 
 /*
  * */
-UNSIGNED_INTEGER
+LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalBytesReceived(const char * controlURL,
 						const char * servicetype)
 {
@@ -48,7 +50,9 @@ UPNP_GetTotalBytesReceived(const char * controlURL,
 	int bufsize = 4096;
 	unsigned int r = 0;
 	char * p;
-	simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*DisplayNameValueList(buffer, bufsize);*/
 	p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
@@ -59,7 +63,7 @@ UPNP_GetTotalBytesReceived(const char * controlURL,
 
 /*
  * */
-UNSIGNED_INTEGER
+LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalPacketsSent(const char * controlURL,
 						const char * servicetype)
 {
@@ -68,7 +72,9 @@ UPNP_GetTotalPacketsSent(const char * controlURL,
 	int bufsize = 4096;
 	unsigned int r = 0;
 	char * p;
-	simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*DisplayNameValueList(buffer, bufsize);*/
 	p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
@@ -79,7 +85,7 @@ UPNP_GetTotalPacketsSent(const char * controlURL,
 
 /*
  * */
-UNSIGNED_INTEGER
+LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalPacketsReceived(const char * controlURL,
 						const char * servicetype)
 {
@@ -88,7 +94,9 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
 	int bufsize = 4096;
 	unsigned int r = 0;
 	char * p;
-	simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*DisplayNameValueList(buffer, bufsize);*/
 	p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
@@ -99,11 +107,12 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
 
 /* UPNP_GetStatusInfo() call the corresponding UPNP method
  * returns the current status and uptime */
-int UPNP_GetStatusInfo(const char * controlURL,
-					const char * servicetype,
-					char * status, 
-					unsigned int * uptime,
-					char * lastconnerror)
+LIBSPEC int
+UPNP_GetStatusInfo(const char * controlURL,
+				const char * servicetype,
+				char * status, 
+				unsigned int * uptime,
+				char * lastconnerror)
 {
 	struct NameValueParserData pdata;
 	char buffer[4096];
@@ -116,7 +125,9 @@ int UPNP_GetStatusInfo(const char * controlURL,
 	if(!status && !uptime)
 		return UPNPCOMMAND_INVALID_ARGS;
 
-	simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*DisplayNameValueList(buffer, bufsize);*/
 	up = GetValueFromNameValueList(&pdata, "NewUptime");
@@ -159,9 +170,10 @@ int UPNP_GetStatusInfo(const char * controlURL,
 
 /* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
  * returns the connection type */
-int UPNP_GetConnectionTypeInfo(const char * controlURL,
-                               const char * servicetype,
-                               char * connectionType)
+LIBSPEC int
+UPNP_GetConnectionTypeInfo(const char * controlURL,
+                           const char * servicetype,
+                           char * connectionType)
 {
 	struct NameValueParserData pdata;
 	char buffer[4096];
@@ -172,8 +184,10 @@ int UPNP_GetConnectionTypeInfo(const char * controlURL,
 	if(!connectionType)
 		return UPNPCOMMAND_INVALID_ARGS;
 
-	simpleUPnPcommand(-1, controlURL, servicetype,
-	                  "GetConnectionTypeInfo", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype,
+	                  "GetConnectionTypeInfo", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	p = GetValueFromNameValueList(&pdata, "NewConnectionType");
 	/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
@@ -198,7 +212,11 @@ int UPNP_GetConnectionTypeInfo(const char * controlURL,
  * One of the values can be null 
  * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only 
  * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
-int UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicetype, unsigned int * bitrateDown, unsigned int* bitrateUp)
+LIBSPEC int
+UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
+                             const char * servicetype,
+                             unsigned int * bitrateDown,
+                             unsigned int* bitrateUp)
 {
 	struct NameValueParserData pdata;
 	char buffer[4096];
@@ -212,9 +230,11 @@ int UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicety
 		return UPNPCOMMAND_INVALID_ARGS;
 
 	/* shouldn't we use GetCommonLinkProperties ? */
-	simpleUPnPcommand(-1, controlURL, servicetype,
-	                  "GetCommonLinkProperties", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype,
+	                  "GetCommonLinkProperties", 0, buffer, &bufsize) < 0) {
 	                  /*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	/*DisplayNameValueList(buffer, bufsize);*/
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
@@ -226,16 +246,14 @@ int UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicety
 	if(down && up)
 		ret = UPNPCOMMAND_SUCCESS;
 
-	if(bitrateDown)
-	{
+	if(bitrateDown) {
 		if(down)
 			sscanf(down,"%u",bitrateDown);
 		else
 			*bitrateDown = 0;
 	}
 
-	if(bitrateUp)
-	{
+	if(bitrateUp) {
 		if(up)
 			sscanf(up,"%u",bitrateUp);
 		else
@@ -262,9 +280,10 @@ int UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicety
  * 402 Invalid Args - See UPnP Device Architecture section on Control.
  * 501 Action Failed - See UPnP Device Architecture section on Control.
  */
-int UPNP_GetExternalIPAddress(const char * controlURL,
-                              const char * servicetype,
-							  char * extIpAdd)
+LIBSPEC int
+UPNP_GetExternalIPAddress(const char * controlURL,
+                          const char * servicetype,
+                          char * extIpAdd)
 {
 	struct NameValueParserData pdata;
 	char buffer[4096];
@@ -275,7 +294,9 @@ int UPNP_GetExternalIPAddress(const char * controlURL,
 	if(!extIpAdd || !controlURL || !servicetype)
 		return UPNPCOMMAND_INVALID_ARGS;
 
-	simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	/*DisplayNameValueList(buffer, bufsize);*/
 	ParseNameValue(buffer, bufsize, &pdata);
 	/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
@@ -297,7 +318,7 @@ int UPNP_GetExternalIPAddress(const char * controlURL,
 	return ret;
 }
 
-int
+LIBSPEC int
 UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
                     const char * extPort,
 					const char * inPort,
@@ -333,7 +354,10 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
 	AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
 	AddPortMappingArgs[7].elt = "NewLeaseDuration";
 	AddPortMappingArgs[7].val = "0";
-	simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize) < 0) {
+		free(AddPortMappingArgs);
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	/*DisplayNameValueList(buffer, bufsize);*/
 	/*buffer[bufsize] = '\0';*/
 	/*puts(buffer);*/
@@ -351,7 +375,7 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
 	return ret;
 }
 
-int
+LIBSPEC int
 UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
                        const char * extPort, const char * proto,
                        const char * remoteHost)
@@ -374,9 +398,12 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
 	DeletePortMappingArgs[1].val = extPort;
 	DeletePortMappingArgs[2].elt = "NewProtocol";
 	DeletePortMappingArgs[2].val = proto;
-	simpleUPnPcommand(-1, controlURL, servicetype,
-	                  "DeletePortMapping",
-					  DeletePortMappingArgs, buffer, &bufsize);
+	if(simpleUPnPcommand(-1, controlURL, servicetype,
+	                     "DeletePortMapping",
+	                     DeletePortMappingArgs, buffer, &bufsize) < 0 ) {
+		free(DeletePortMappingArgs);
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	/*DisplayNameValueList(buffer, bufsize);*/
 	ParseNameValue(buffer, bufsize, &pdata);
 	resVal = GetValueFromNameValueList(&pdata, "errorCode");
@@ -391,17 +418,18 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
 	return ret;
 }
 
-int UPNP_GetGenericPortMappingEntry(const char * controlURL,
-                                     const char * servicetype,
-									 const char * index,
-									 char * extPort,
-									 char * intClient,
-									 char * intPort,
-									 char * protocol,
-									 char * desc,
-									 char * enabled,
-									 char * rHost,
-									 char * duration)
+LIBSPEC int
+UPNP_GetGenericPortMappingEntry(const char * controlURL,
+                                const char * servicetype,
+							 const char * index,
+							 char * extPort,
+							 char * intClient,
+							 char * intPort,
+							 char * protocol,
+							 char * desc,
+							 char * enabled,
+							 char * rHost,
+							 char * duration)
 {
 	struct NameValueParserData pdata;
 	struct UPNParg * GetPortMappingArgs;
@@ -416,9 +444,12 @@ int UPNP_GetGenericPortMappingEntry(const char * controlURL,
 	GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
 	GetPortMappingArgs[0].elt = "NewPortMappingIndex";
 	GetPortMappingArgs[0].val = index;
-	simpleUPnPcommand(-1, controlURL, servicetype,
+	if(simpleUPnPcommand(-1, controlURL, servicetype,
 	                  "GetGenericPortMappingEntry",
-					  GetPortMappingArgs, buffer, &bufsize);
+					  GetPortMappingArgs, buffer, &bufsize) < 0) {
+		free(GetPortMappingArgs);
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	ParseNameValue(buffer, bufsize, &pdata);
 	p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
 	if(p && rHost)
@@ -480,14 +511,19 @@ int UPNP_GetGenericPortMappingEntry(const char * controlURL,
 	return r;
 }
 
-int UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries)
+LIBSPEC int
+UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
+                                   const char * servicetype,
+                                   unsigned int * numEntries)
 {
  	struct NameValueParserData pdata;
  	char buffer[4096];
  	int bufsize = 4096;
  	char* p;
 	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
- 	simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize);
+ 	if(simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize) < 0) {
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 #ifdef DEBUG
 	DisplayNameValueList(buffer, bufsize);
 #endif
@@ -513,7 +549,7 @@ int UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * ser
 /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
  * the result is returned in the intClient and intPort strings
  * please provide 16 and 6 bytes of data */
-int
+LIBSPEC int
 UPNP_GetSpecificPortMappingEntry(const char * controlURL,
                                  const char * servicetype,
                                  const char * extPort,
@@ -537,10 +573,12 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
 	GetPortMappingArgs[1].val = extPort;
 	GetPortMappingArgs[2].elt = "NewProtocol";
 	GetPortMappingArgs[2].val = proto;
-	simpleUPnPcommand(-1, controlURL, servicetype,
-	                  "GetSpecificPortMappingEntry",
-					  GetPortMappingArgs, buffer, &bufsize);
-	/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */
+	if(simpleUPnPcommand(-1, controlURL, servicetype,
+	                     "GetSpecificPortMappingEntry",
+	                     GetPortMappingArgs, buffer, &bufsize) < 0) {
+		free(GetPortMappingArgs);
+		return UPNPCOMMAND_HTTP_ERROR;
+	}
 	/*DisplayNameValueList(buffer, bufsize);*/
 	ParseNameValue(buffer, bufsize, &pdata);
 
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnpcommands.h b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpcommands.h
similarity index 97%
rename from libportfwd/third-party/miniupnpc-20090605/upnpcommands.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnpcommands.h
index 217c472be..5561beaae 100644
--- a/libportfwd/third-party/miniupnpc-20090605/upnpcommands.h
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpcommands.h
@@ -1,7 +1,7 @@
-/* $Id: upnpcommands.h,v 1.17 2009/04/17 21:21:19 nanard Exp $ */
+/* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
 /* Miniupnp project : http://miniupnp.free.fr/
  * Author : Thomas Bernard
- * Copyright (c) 2005-2008 Thomas Bernard
+ * Copyright (c) 2005-2010 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided within this distribution */
 #ifndef __UPNPCOMMANDS_H__
@@ -14,6 +14,7 @@
 #define UPNPCOMMAND_SUCCESS (0)
 #define UPNPCOMMAND_UNKNOWN_ERROR (-1)
 #define UPNPCOMMAND_INVALID_ARGS (-2)
+#define UPNPCOMMAND_HTTP_ERROR (-3)
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnperrors.c b/libportfwd/third-party/miniupnpc-1.4.20100609/upnperrors.c
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/upnperrors.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnperrors.c
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnperrors.h b/libportfwd/third-party/miniupnpc-1.4.20100609/upnperrors.h
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/upnperrors.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnperrors.h
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnpreplyparse.c b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpreplyparse.c
similarity index 100%
rename from libportfwd/third-party/miniupnpc-20090605/upnpreplyparse.c
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnpreplyparse.c
diff --git a/libportfwd/third-party/miniupnpc-20090605/upnpreplyparse.h b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpreplyparse.h
similarity index 87%
rename from libportfwd/third-party/miniupnpc-20090605/upnpreplyparse.h
rename to libportfwd/third-party/miniupnpc-1.4.20100609/upnpreplyparse.h
index a92763431..fb7d4535c 100644
--- a/libportfwd/third-party/miniupnpc-20090605/upnpreplyparse.h
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/upnpreplyparse.h
@@ -1,14 +1,14 @@
-/* $Id: upnpreplyparse.h,v 1.8 2008/02/21 13:05:27 nanard Exp $ */
+/* $Id: upnpreplyparse.h,v 1.10 2009/07/09 16:01:50 nanard Exp $ */
 /* MiniUPnP project
  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006 Thomas Bernard 
+ * (c) 2006-2009 Thomas Bernard 
  * This software is subject to the conditions detailed
  * in the LICENCE file provided within the distribution */
 
 #ifndef __UPNPREPLYPARSE_H__
 #define __UPNPREPLYPARSE_H__
 
-#if defined(NO_SYS_QUEUE_H) || defined(WIN32)
+#if defined(NO_SYS_QUEUE_H) || defined(WIN32) || defined(__HAIKU__) 
 #include "bsdqueue.h"
 #else
 #include <sys/queue.h>
diff --git a/libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c b/libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c
new file mode 100644
index 000000000..0da8bedfc
--- /dev/null
+++ b/libportfwd/third-party/miniupnpc-1.4.20100609/wingenminiupnpcstrings.c
@@ -0,0 +1,69 @@
+/* $Id: wingenminiupnpcstrings.c,v 1.1 2009/12/10 18:46:15 nanard Exp $ */
+/* Project: miniupnp
+ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
+ * Author: Thomas Bernard
+ * Copyright (c) 2005-2009 Thomas Bernard
+ * This software is subjects to the conditions detailed
+ * in the LICENSE file provided within this distribution */
+#include <stdio.h>
+#include <windows.h>
+
+/* This program display the Windows version and is used to
+ * generate the miniupnpcstrings.h
+ * wingenminiupnpcstrings miniupnpcstrings.h.in miniupnpcstrings.h
+ */
+int main(int argc, char * * argv) {
+	char buffer[256];
+	OSVERSIONINFO osvi;
+	FILE * fin;
+	FILE * fout;
+	int n;
+	/* dwMajorVersion :
+       The major version number of the operating system. For more information, see Remarks.
+     dwMinorVersion :
+       The minor version number of the operating system. For more information, see Remarks.
+     dwBuildNumber :
+       The build number of the operating system.
+     dwPlatformId
+       The operating system platform. This member can be the following value. 
+     szCSDVersion
+       A null-terminated string, such as "Service Pack 3", that indicates the
+       latest Service Pack installed on the system. If no Service Pack has
+       been installed, the string is empty.
+   */
+  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+  GetVersionEx(&osvi);
+
+	printf("Windows %lu.%lu Build %lu %s\n",
+	       osvi.dwMajorVersion, osvi.dwMinorVersion,
+	       osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion));
+
+	if(argc >= 3) {
+		fin = fopen(argv[1], "r");
+		if(!fin) {
+			fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
+			return 1;
+		}
+		fout = fopen(argv[2], "w");
+		if(!fout) {
+			fprintf(stderr, "Cannot open %s for writing.\n", argv[2]);
+			return 1;
+		}
+		n = 0;
+		while(fgets(buffer, sizeof(buffer), fin)) {
+			if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) {
+				sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n",
+				        osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
+			}
+			/*fputs(buffer, stdout);*/
+			fputs(buffer, fout);
+			n++;
+		}
+		fclose(fin);
+		fclose(fout);
+		printf("%d lines written to %s.\n", n, argv[2]);
+	}
+  return 0;
+}