From 0dba07197c2a7c4b480e070e9f9a52aa92b92883 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 9 Jul 2008 02:51:29 +0000 Subject: [PATCH] Update to the 20080707 version of libnatpmp and the 20080703 version of miniupnpc --- third-party/libnatpmp/README | 2 +- third-party/libnatpmp/getgateway.c | 195 +++++++++++++++++++++++++++-- third-party/libnatpmp/getgateway.h | 10 +- third-party/libnatpmp/natpmp.c | 23 +++- third-party/libnatpmp/natpmp.h | 19 +-- third-party/miniupnp/LICENCE | 2 +- third-party/miniupnp/README | 2 +- 7 files changed, 228 insertions(+), 25 deletions(-) diff --git a/third-party/libnatpmp/README b/third-party/libnatpmp/README index 28abe43aa..c9340a987 100644 --- a/third-party/libnatpmp/README +++ b/third-party/libnatpmp/README @@ -1,4 +1,4 @@ libnatpmp is written by Thomas Bernard. Its homepage is http://miniupnp.tuxfamily.org/libnatpmp.html -This code is from the libnatpmp-20080630 snapshot +This code is from the libnatpmp-20080707 snapshot diff --git a/third-party/libnatpmp/getgateway.c b/third-party/libnatpmp/getgateway.c index c7dc00cb6..ae6ea06a7 100644 --- a/third-party/libnatpmp/getgateway.c +++ b/third-party/libnatpmp/getgateway.c @@ -1,4 +1,4 @@ -/* $Id: getgateway.c,v 1.8 2008/06/30 14:15:40 nanard Exp $ */ +/* $Id: getgateway.c,v 1.11 2008/07/02 23:56:11 nanard Exp $ */ /* libnatpmp * Copyright (c) 2007-2008, Thomas BERNARD * @@ -15,7 +15,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include +#ifndef WIN32 #include +#endif #include /* There is no portable method to get the default route gateway. * So below are three differents functions implementing this. @@ -24,14 +26,34 @@ * Many systems should provide route information through raw PF_ROUTE * sockets. */ #ifdef __linux__ - #define USE_PROC_NET_ROUTE -#elif defined(__APPLE__) - #define USE_SYSCTL_NET_ROUTE -#elif defined(BSD) - /*#define USE_SYSCTL_NET_ROUTE*/ - #define USE_SOCKET_ROUTE -#elif (defined(sun) && defined(__SVR4)) - #define USE_SOCKET_ROUTE +#define USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#endif + +#ifdef BSD +#undef USE_PROC_NET_ROUTE +#define USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#endif + +#ifdef __APPLE__ +#undef USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#define USE_SYSCTL_NET_ROUTE +#endif + +#if (defined(sun) && defined(__SVR4)) +#undef USE_PROC_NET_ROUTE +#define USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#endif + +#ifdef WIN32 +#undef USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#define USE_WIN32_CODE #endif #ifdef USE_SYSCTL_NET_ROUTE @@ -47,10 +69,18 @@ #include #include #endif +#ifdef WIN32 +#include +#include +#define MAX_KEY_LENGTH 255 +#define MAX_VALUE_LENGTH 16383 +#endif #include "getgateway.h" +#ifndef WIN32 #define SUCCESS (0) #define FAILED (-1) +#endif #ifdef USE_PROC_NET_ROUTE int getdefaultgateway(in_addr_t * addr) @@ -229,3 +259,150 @@ int getdefaultgateway(in_addr_t *addr) } #endif /* #ifdef USE_SOCKET_ROUTE */ +#ifdef USE_WIN32_CODE +int getdefaultgateway(in_addr_t * addr) +{ + HKEY networkCardsKey; + HKEY networkCardKey; + HKEY interfacesKey; + HKEY interfaceKey; + DWORD i = 0; + DWORD numSubKeys = 0; + TCHAR keyName[MAX_KEY_LENGTH]; + DWORD keyNameLength = MAX_KEY_LENGTH; + TCHAR keyValue[MAX_VALUE_LENGTH]; + DWORD keyValueLength = MAX_VALUE_LENGTH; + DWORD keyValueType = REG_SZ; + TCHAR gatewayValue[MAX_VALUE_LENGTH]; + DWORD gatewayValueLength = MAX_VALUE_LENGTH; + DWORD gatewayValueType = REG_MULTI_SZ; + int done = 0; + + char networkCardsPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + char interfacesPath[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; + + // The windows registry lists its primary network devices in the following location: + // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards + // + // Each network device has its own subfolder, named with an index, with various properties: + // -NetworkCards + // -5 + // -Description = Broadcom 802.11n Network Adapter + // -ServiceName = {E35A72F8-5065-4097-8DFE-C7790774EE4D} + // -8 + // -Description = Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller + // -ServiceName = {86226414-5545-4335-A9D1-5BD7120119AD} + // + // The above service name is the name of a subfolder within: + // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces + // + // There may be more subfolders in this interfaces path than listed in the network cards path above: + // -Interfaces + // -{3a539854-6a70-11db-887c-806e6f6e6963} + // -DhcpIPAddress = 0.0.0.0 + // -[more] + // -{E35A72F8-5065-4097-8DFE-C7790774EE4D} + // -DhcpIPAddress = 10.0.1.4 + // -DhcpDefaultGateway = 10.0.1.1 + // -[more] + // -{86226414-5545-4335-A9D1-5BD7120119AD} + // -DhcpIpAddress = 10.0.1.5 + // -DhcpDefaultGateay = 10.0.1.1 + // -[more] + // + // In order to extract this information, we enumerate each network card, and extract the ServiceName value. + // This is then used to open the interface subfolder, and attempt to extract a DhcpDefaultGateway value. + // Once one is found, we're done. + // + // It may be possible to simply enumerate the interface folders until we find one with a DhcpDefaultGateway value. + // However, the technique used is the technique most cited on the web, and we assume it to be more correct. + + if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predifined key + networkCardsPath, // Name of registry subkey to open + 0, // Reserved - must be zero + KEY_READ, // Mask - desired access rights + &networkCardsKey)) // Pointer to output key + { + // Unable to open network cards keys + return -1; + } + + if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predefined key + interfacesPath, // Name of registry subkey to open + 0, // Reserved - must be zero + KEY_READ, // Mask - desired access rights + &interfacesKey)) // Pointer to output key + { + // Unable to open interfaces key + RegCloseKey(networkCardsKey); + return -1; + } + + // Figure out how many subfolders are within the NetworkCards folder + RegQueryInfoKey(networkCardsKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + //printf( "Number of subkeys: %u\n", (unsigned int)numSubKeys); + + // Enumrate through each subfolder within the NetworkCards folder + for(i = 0; i < numSubKeys && !done; i++) + { + keyNameLength = MAX_KEY_LENGTH; + if(ERROR_SUCCESS == RegEnumKeyEx(networkCardsKey, // Open registry key + i, // Index of subkey to retrieve + keyName, // Buffer that receives the name of the subkey + &keyNameLength, // Variable that receives the size of the above buffer + NULL, // Reserved - must be NULL + NULL, // Buffer that receives the class string + NULL, // Variable that receives the size of the above buffer + NULL)) // Variable that receives the last write time of subkey + { + if(RegOpenKeyEx(networkCardsKey, keyName, 0, KEY_READ, &networkCardKey) == ERROR_SUCCESS) + { + keyValueLength = MAX_VALUE_LENGTH; + if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey, // Open registry key + "ServiceName", // Name of key to query + NULL, // Reserved - must be NULL + &keyValueType, // Receives value type + keyValue, // Receives value + &keyValueLength)) // Receives value length in bytes + { + //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 + NULL, // Reserved - must be NULL + &gatewayValueType, // Receives value type + 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) + { + //printf("gatewayValue: %s\n", gatewayValue); + done = 1; + } + } + RegCloseKey(interfaceKey); + } + } + RegCloseKey(networkCardKey); + } + } + } + + RegCloseKey(interfacesKey); + RegCloseKey(networkCardsKey); + + if(done) + { + *addr = inet_addr(gatewayValue); + return 0; + } + + return -1; +} +#endif /* #ifdef USE_WIN32_CODE */ + diff --git a/third-party/libnatpmp/getgateway.h b/third-party/libnatpmp/getgateway.h index e00483e3b..cf7794600 100644 --- a/third-party/libnatpmp/getgateway.h +++ b/third-party/libnatpmp/getgateway.h @@ -1,4 +1,4 @@ -/* $Id: getgateway.h,v 1.2 2007/11/22 18:01:37 nanard Exp $ */ +/* $Id: getgateway.h,v 1.3 2008/07/02 22:33:06 nanard Exp $ */ /* libnatpmp * Copyright (c) 2007, Thomas BERNARD * @@ -16,10 +16,16 @@ #ifndef __GETGATEWAY_H__ #define __GETGATEWAY_H__ +#ifdef WIN32 +#include +#define in_addr_t uint32_t +#endif +#include "declspec.h" + /* getdefaultgateway() : * return value : * 0 : success * -1 : failure */ -int getdefaultgateway(in_addr_t * addr); +LIBSPEC int getdefaultgateway(in_addr_t * addr); #endif diff --git a/third-party/libnatpmp/natpmp.c b/third-party/libnatpmp/natpmp.c index 3fe730ae3..9ea3a053e 100644 --- a/third-party/libnatpmp/natpmp.c +++ b/third-party/libnatpmp/natpmp.c @@ -1,4 +1,4 @@ -/* $Id: natpmp.c,v 1.7 2008/05/29 08:06:01 nanard Exp $ */ +/* $Id: natpmp.c,v 1.8 2008/07/02 22:33:06 nanard Exp $ */ /* libnatpmp * Copyright (c) 2007-2008, Thomas BERNARD * http://miniupnp.free.fr/libnatpmp.html @@ -21,19 +21,26 @@ #include #include #include +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ECONNREFUSED WSAECONNREFUSED #else #include #include #include #include #include +#define closesocket close #endif #include "natpmp.h" #include "getgateway.h" int initnatpmp(natpmp_t * p) { +#ifdef WIN32 + u_long ioctlArg = 1; +#else int flags; +#endif struct sockaddr_in addr; if(!p) return NATPMP_ERR_INVALIDARGS; @@ -41,10 +48,15 @@ int initnatpmp(natpmp_t * p) p->s = socket(PF_INET, SOCK_DGRAM, 0); if(p->s < 0) return NATPMP_ERR_SOCKETERROR; +#ifdef WIN32 + if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR) + return NATPMP_ERR_FCNTLERROR; +#else if((flags = fcntl(p->s, F_GETFL, 0)) < 0) return NATPMP_ERR_FCNTLERROR; if(fcntl(p->s, F_SETFL, flags | O_NONBLOCK) < 0) return NATPMP_ERR_FCNTLERROR; +#endif if(getdefaultgateway(&(p->gateway)) < 0) return NATPMP_ERR_CANNOTGETGATEWAY; @@ -62,7 +74,7 @@ int closenatpmp(natpmp_t * p) { if(!p) return NATPMP_ERR_INVALIDARGS; - if(close(p->s) < 0) + if(closesocket(p->s) < 0) return NATPMP_ERR_CLOSEERR; return 0; } @@ -160,7 +172,8 @@ int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response) (struct sockaddr *)&addr, &addrlen); if(n<0) switch(errno) { - case EAGAIN: + /*case EAGAIN:*/ + case EWOULDBLOCK: n = NATPMP_TRYAGAIN; break; case ECONNREFUSED: @@ -269,7 +282,11 @@ const char * strnatpmperr(int r) s = "cannot get default gateway ip address"; break; case NATPMP_ERR_CLOSEERR: +#ifdef WIN32 + s = "closesocket() failed"; +#else s = "close() failed"; +#endif break; case NATPMP_ERR_RECVFROM: s = "recvfrom() failed"; diff --git a/third-party/libnatpmp/natpmp.h b/third-party/libnatpmp/natpmp.h index 0713dd0e8..9470543f7 100644 --- a/third-party/libnatpmp/natpmp.h +++ b/third-party/libnatpmp/natpmp.h @@ -1,4 +1,4 @@ -/* $Id: natpmp.h,v 1.9 2008/05/29 08:06:01 nanard Exp $ */ +/* $Id: natpmp.h,v 1.10 2008/07/02 22:33:06 nanard Exp $ */ /* libnatpmp * Copyright (c) 2007-2008, Thomas BERNARD * http://miniupnp.free.fr/libnatpmp.html @@ -24,9 +24,12 @@ #include #ifdef WIN32 #include +#include +#define in_addr_t uint32_t #else #include #endif +#include "declspec.h" typedef struct { int s; /* socket */ @@ -113,7 +116,7 @@ typedef struct { * NATPMP_ERR_FCNTLERROR * NATPMP_ERR_CANNOTGETGATEWAY * NATPMP_ERR_CONNECTERR */ -int initnatpmp(natpmp_t * p); +LIBSPEC int initnatpmp(natpmp_t * p); /* closenatpmp() * close resources associated with a natpmp_t object @@ -121,7 +124,7 @@ int initnatpmp(natpmp_t * p); * 0 = OK * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_CLOSEERR */ -int closenatpmp(natpmp_t * p); +LIBSPEC int closenatpmp(natpmp_t * p); /* sendpublicaddressrequest() * send a public address NAT-PMP request to the network gateway @@ -129,7 +132,7 @@ int closenatpmp(natpmp_t * p); * 2 = OK (size of the request) * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_SENDERR */ -int sendpublicaddressrequest(natpmp_t * p); +LIBSPEC int sendpublicaddressrequest(natpmp_t * p); /* sendnewportmappingrequest() * send a new port mapping NAT-PMP request to the network gateway @@ -143,7 +146,7 @@ int sendpublicaddressrequest(natpmp_t * p); * 12 = OK (size of the request) * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_SENDERR */ -int sendnewportmappingrequest(natpmp_t * p, int protocol, +LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, uint16_t privateport, uint16_t publicport, uint32_t lifetime); @@ -155,7 +158,7 @@ int sendnewportmappingrequest(natpmp_t * p, int protocol, * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_GETTIMEOFDAYERR * NATPMP_ERR_NOPENDINGREQ */ -int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout); +LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout); /* readnatpmpresponseorretry() * fills the natpmpresp_t structure if possible @@ -174,10 +177,10 @@ int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout); * NATPMP_ERR_OUTOFRESOURCES * NATPMP_ERR_UNSUPPORTEDOPCODE * NATPMP_ERR_UNDEFINEDERROR */ -int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response); +LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response); #ifdef ENABLE_STRNATPMPERR -const char * strnatpmperr(int t); +LIBSPEC const char * strnatpmperr(int t); #endif #endif diff --git a/third-party/miniupnp/LICENCE b/third-party/miniupnp/LICENCE index 185eecc48..a8cfb5ef3 100644 --- a/third-party/miniupnp/LICENCE +++ b/third-party/miniupnp/LICENCE @@ -1,4 +1,4 @@ -Copyright (c) 2005-2007, Thomas BERNARD +Copyright (c) 2005-2008, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/third-party/miniupnp/README b/third-party/miniupnp/README index 0e35a5f53..599e99616 100644 --- a/third-party/miniupnp/README +++ b/third-party/miniupnp/README @@ -1,3 +1,3 @@ MiniUPnP is written by Thomas Bernard. Its homepage is http://miniupnp.free.fr/ -This is from the miniupnp-20080428 snapshot +This is from the miniupnp-20080703 snapshot -- 2.40.0