libnatpmp-20110808/Changelog.txt010064400017500000024000000035361162005140600155610ustar00nanardstaff$Id: Changelog.txt,v 1.29 2011/08/07 16:59:33 nanard Exp $ 2011/08/07: Patch to build on debian/kFreeBSD. 2011/07/15: Put 3 clauses BSD licence at the top of source files. 2011/06/18: --no-undefined => -Wl,--no-undefined adding a natpmpc.1 man page 2011/05/19: Small fix in libnatpmpmodule.c thanks to Manuel Mausz 2011/01/03: Added an argument to initnatpmp() in order to force the gateway to be used 2011/01/01: fix in make install 2010/05/21: make install now working under MacOSX (and BSD) 2010/04/12: cplusplus stuff in natpmp.h 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 libnatpmp-20110808/Makefile010064400017500000024000000047111160046616000145720ustar00nanardstaff# $Id: Makefile,v 1.18 2011/06/22 21:32:30 nanard Exp $ # This Makefile is designed for use with GNU make # libnatpmp # (c) 2007-2011 Thomas Bernard # http://miniupnp.free.fr/libnatpmp.html OS = $(shell uname -s) CC = gcc INSTALL = install # APIVERSION is used in soname APIVERSION = 1 #LDFLAGS = -Wl,--no-undefined CFLAGS = -O -fPIC -Wall -DENABLE_STRNATPMPERR LIBOBJS = natpmp.o getgateway.o OBJS = $(LIBOBJS) testgetgateway.o natpmpc.o STATICLIB = libnatpmp.a ifeq ($(OS), Darwin) SHAREDLIB = libnatpmp.dylib SONAME = $(basename $(SHAREDLIB)).$(APIVERSION).dylib CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS) else SHAREDLIB = libnatpmp.so SONAME = $(SHAREDLIB).$(APIVERSION) endif HEADERS = natpmp.h EXECUTABLES = testgetgateway natpmpc-shared natpmpc-static INSTALLPREFIX ?= $(PREFIX)/usr INSTALLDIRINC = $(INSTALLPREFIX)/include INSTALLDIRLIB = $(INSTALLPREFIX)/lib INSTALLDIRBIN = $(INSTALLPREFIX)/bin .PHONY: all clean depend install cleaninstall installpythonmodule all: $(STATICLIB) $(SHAREDLIB) $(EXECUTABLES) pythonmodule: $(STATICLIB) libnatpmpmodule.c setup.py python setup.py build touch $@ installpythonmodule: pythonmodule python setup.py install clean: $(RM) $(OBJS) $(EXECUTABLES) $(STATICLIB) $(SHAREDLIB) $(RM) pythonmodule $(RM) -r build/ dist/ depend: makedepend -f$(MAKEFILE_LIST) -Y $(OBJS:.o=.c) 2>/dev/null install: $(HEADERS) $(STATICLIB) $(SHAREDLIB) natpmpc-shared $(INSTALL) -d $(INSTALLDIRINC) $(INSTALL) -m 644 $(HEADERS) $(INSTALLDIRINC) $(INSTALL) -d $(INSTALLDIRLIB) $(INSTALL) -m 644 $(STATICLIB) $(INSTALLDIRLIB) $(INSTALL) -m 644 $(SHAREDLIB) $(INSTALLDIRLIB)/$(SONAME) $(INSTALL) -d $(INSTALLDIRBIN) $(INSTALL) -m 755 natpmpc-shared $(INSTALLDIRBIN)/natpmpc ln -s -f $(SONAME) $(INSTALLDIRLIB)/$(SHAREDLIB) cleaninstall: $(RM) $(addprefix $(INSTALLDIRINC), $(HEADERS)) $(RM) $(INSTALLDIRLIB)/$(SONAME) $(RM) $(INSTALLDIRLIB)/$(SHAREDLIB) $(RM) $(INSTALLDIRLIB)/$(STATICLIB) testgetgateway: testgetgateway.o getgateway.o natpmpc-static: natpmpc.o $(STATICLIB) $(CC) $(LDFLAGS) -o $@ $^ natpmpc-shared: natpmpc.o $(SHAREDLIB) $(CC) $(LDFLAGS) -o $@ $^ $(STATICLIB): $(LIBOBJS) $(AR) crs $@ $? $(SHAREDLIB): $(LIBOBJS) ifeq ($(OS), Darwin) $(CC) -dynamiclib -Wl,-install_name,$(SONAME) -o $@ $^ else $(CC) -shared -Wl,-soname,$(SONAME) -o $@ $^ endif # DO NOT DELETE natpmp.o: natpmp.h getgateway.h declspec.h getgateway.o: getgateway.h declspec.h testgetgateway.o: getgateway.h declspec.h natpmpc.o: natpmp.h libnatpmp-20110808/getgateway.c010064400017500000024000000436131162005146300154410ustar00nanardstaff/* $Id: getgateway.c,v 1.22 2011/08/08 21:20:51 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #include #include #ifndef WIN32 #include #endif #if !defined(_MSC_VER) #include #endif /* There is no portable method to get the default route gateway. * 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. * 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 #undef USE_SYSCTL_NET_ROUTE #endif #if defined(BSD) || defined(__FreeBSD_kernel__) #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 #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 #include #include #include #endif #ifdef __HAIKU__ #include #include #include #include #define USE_HAIKU_CODE #endif #ifdef USE_SYSCTL_NET_ROUTE #include #include #include #include #endif #ifdef USE_SOCKET_ROUTE #include #include #include #include #include #endif #ifdef USE_WIN32_CODE #include #include #define MAX_KEY_LENGTH 255 #define MAX_VALUE_LENGTH 16383 #endif #ifdef USE_WIN32_CODE_2 #include #include #endif #include "getgateway.h" #ifndef WIN32 #define SUCCESS (0) #define FAILED (-1) #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) { unsigned long d, g; char buf[256]; int line = 0; FILE * f; char * p; f = fopen("/proc/net/route", "r"); if(!f) return FAILED; while(fgets(buf, sizeof(buf), f)) { 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 && g != 0) { /* default */ *addr = g; fclose(f); return SUCCESS; } } } line++; } /* default route not found ! */ if(f) fclose(f); return FAILED; } #endif /* #ifdef USE_PROC_NET_ROUTE */ #ifdef USE_SYSCTL_NET_ROUTE #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) int getdefaultgateway(in_addr_t * addr) { #if 0 /* net.route.0.inet.dump.0.0 ? */ int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0, 0/*tableid*/}; #endif /* net.route.0.inet.flags.gateway */ int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY}; size_t l; char * buf, * p; struct rt_msghdr * rt; struct sockaddr * sa; struct sockaddr * sa_tab[RTAX_MAX]; int i; int r = FAILED; if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) { return FAILED; } if(l>0) { buf = malloc(l); if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) { free(buf); return FAILED; } for(p=buf; prtm_msglen) { rt = (struct rt_msghdr *)p; sa = (struct sockaddr *)(rt + 1); for(i=0; irtm_addrs & (1 << i)) { sa_tab[i] = sa; sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); } else { sa_tab[i] = NULL; } } if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) && sa_tab[RTAX_DST]->sa_family == AF_INET && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) { if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) { *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr; r = SUCCESS; } } } free(buf); } return r; } #endif /* #ifdef USE_SYSCTL_NET_ROUTE */ #ifdef USE_SOCKET_ROUTE /* Thanks to Darren Kenny for this code */ #define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ l = sizeof(struct sockaddr); memmove(cp, &(u), l); cp += l;\ } #define rtm m_rtmsg.m_rtm struct { struct rt_msghdr m_rtm; char m_space[512]; } m_rtmsg; int getdefaultgateway(in_addr_t *addr) { int s, seq, l, rtm_addrs, i; pid_t pid; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; struct rt_msghdr *msg_hdr; pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; memset(&so_dst, 0, sizeof(so_dst)); memset(&so_mask, 0, sizeof(so_mask)); memset(&rtm, 0, sizeof(struct rt_msghdr)); rtm.rtm_type = RTM_GET; rtm.rtm_flags = RTF_UP | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; so_mask.sa_family = AF_INET; NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; s = socket(PF_ROUTE, SOCK_RAW, 0); if (write(s, (char *)&m_rtmsg, l) < 0) { close(s); return FAILED; } do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); close(s); msg_hdr = &rtm; cp = ((char *)(msg_hdr + 1)); if (msg_hdr->rtm_addrs) { for (i = 1; i; i <<= 1) if (i & msg_hdr->rtm_addrs) { sa = (struct sockaddr *)cp; if (i == RTA_GATEWAY ) gate = sa; cp += sizeof(struct sockaddr); } } else { return FAILED; } if (gate != NULL ) { *addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr; return SUCCESS; } else { return FAILED; } } #endif /* #ifdef USE_SOCKET_ROUTE */ #ifdef USE_WIN32_CODE LIBSPEC 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; //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 // // 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 STR_SERVICENAME, // Name of key to query NULL, // Reserved - must be NULL &keyValueType, // Receives value type (LPBYTE)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 STR_DHCPDEFAULTGATEWAY, // Name of key to query NULL, // Reserved - must be NULL &gatewayValueType, // Receives value type (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) && (gatewayValueLength > 1)) { //printf("gatewayValue: %s\n", gatewayValue); done = 1; } } else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key STR_DEFAULTGATEWAY, // Name of key to query NULL, // Reserved - must be NULL &gatewayValueType, // Receives value type (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) && (gatewayValueLength > 1)) { //printf("gatewayValue: %s\n", gatewayValue); done = 1; } } RegCloseKey(interfaceKey); } } RegCloseKey(networkCardKey); } } } RegCloseKey(interfacesKey); RegCloseKey(networkCardsKey); 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; } return -1; } #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 */ libnatpmp-20110808/getgateway.h010064400017500000024000000036151160777525500154650ustar00nanardstaff/* $Id: getgateway.h,v 1.5 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #ifndef __GETGATEWAY_H__ #define __GETGATEWAY_H__ #ifdef WIN32 #if !defined(_MSC_VER) #include #else typedef unsigned long uint32_t; typedef unsigned short uint16_t; #endif #define in_addr_t uint32_t #endif #include "declspec.h" /* getdefaultgateway() : * return value : * 0 : success * -1 : failure */ LIBSPEC int getdefaultgateway(in_addr_t * addr); #endif libnatpmp-20110808/natpmp.c010064400017500000024000000233321160777525500146140ustar00nanardstaff/* $Id: natpmp.c,v 1.14 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #ifdef __linux__ #define _BSD_SOURCE 1 #endif #include #include #if !defined(_MSC_VER) #include #endif #ifdef WIN32 #include #include #include #include #define EWOULDBLOCK WSAEWOULDBLOCK #define ECONNREFUSED WSAECONNREFUSED #include "wingettimeofday.h" #else #include #include #include #include #include #define closesocket close #endif #include "natpmp.h" #include "getgateway.h" LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw) { #ifdef WIN32 u_long ioctlArg = 1; #else int flags; #endif struct sockaddr_in addr; if(!p) return NATPMP_ERR_INVALIDARGS; memset(p, 0, sizeof(natpmp_t)); 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(forcegw) { p->gateway = forcedgw; } else { if(getdefaultgateway(&(p->gateway)) < 0) return NATPMP_ERR_CANNOTGETGATEWAY; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(NATPMP_PORT); addr.sin_addr.s_addr = p->gateway; if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0) return NATPMP_ERR_CONNECTERR; return 0; } LIBSPEC int closenatpmp(natpmp_t * p) { if(!p) return NATPMP_ERR_INVALIDARGS; if(closesocket(p->s) < 0) return NATPMP_ERR_CLOSEERR; return 0; } int sendpendingrequest(natpmp_t * p) { int r; /* struct sockaddr_in addr;*/ if(!p) return NATPMP_ERR_INVALIDARGS; /* memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(NATPMP_PORT); addr.sin_addr.s_addr = p->gateway; r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0, (struct sockaddr *)&addr, sizeof(addr));*/ r = (int)send(p->s, p->pending_request, p->pending_request_len, 0); return (r<0) ? NATPMP_ERR_SENDERR : r; } int sendnatpmprequest(natpmp_t * p) { int n; if(!p) return NATPMP_ERR_INVALIDARGS; /* TODO : check if no request is allready pending */ p->has_pending_request = 1; p->try_number = 1; n = sendpendingrequest(p); gettimeofday(&p->retry_time, NULL); // check errors ! p->retry_time.tv_usec += 250000; /* add 250ms */ if(p->retry_time.tv_usec >= 1000000) { p->retry_time.tv_usec -= 1000000; p->retry_time.tv_sec++; } return n; } LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout) { struct timeval now; if(!p || !timeout) return NATPMP_ERR_INVALIDARGS; if(!p->has_pending_request) return NATPMP_ERR_NOPENDINGREQ; if(gettimeofday(&now, NULL) < 0) return NATPMP_ERR_GETTIMEOFDAYERR; timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec; timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec; if(timeout->tv_usec < 0) { timeout->tv_usec += 1000000; timeout->tv_sec--; } return 0; } LIBSPEC int sendpublicaddressrequest(natpmp_t * p) { if(!p) return NATPMP_ERR_INVALIDARGS; //static const unsigned char request[] = { 0, 0 }; p->pending_request[0] = 0; p->pending_request[1] = 0; p->pending_request_len = 2; // TODO: return 0 instead of sizeof(request) ?? return sendnatpmprequest(p); } LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, uint16_t privateport, uint16_t publicport, uint32_t lifetime) { if(!p || (protocol!=NATPMP_PROTOCOL_TCP && protocol!=NATPMP_PROTOCOL_UDP)) return NATPMP_ERR_INVALIDARGS; p->pending_request[0] = 0; p->pending_request[1] = protocol; p->pending_request[2] = 0; p->pending_request[3] = 0; *((uint16_t *)(p->pending_request + 4)) = htons(privateport); *((uint16_t *)(p->pending_request + 6)) = htons(publicport); *((uint32_t *)(p->pending_request + 8)) = htonl(lifetime); p->pending_request_len = 12; return sendnatpmprequest(p); } LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response) { unsigned char buf[16]; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); int n; if(!p) return NATPMP_ERR_INVALIDARGS; n = recvfrom(p->s, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen); if(n<0) switch(errno) { /*case EAGAIN:*/ case EWOULDBLOCK: n = NATPMP_TRYAGAIN; break; case ECONNREFUSED: n = NATPMP_ERR_NOGATEWAYSUPPORT; break; default: n = NATPMP_ERR_RECVFROM; } /* check that addr is correct (= gateway) */ else if(addr.sin_addr.s_addr != p->gateway) n = NATPMP_ERR_WRONGPACKETSOURCE; else { response->resultcode = ntohs(*((uint16_t *)(buf + 2))); response->epoch = ntohl(*((uint32_t *)(buf + 4))); if(buf[0] != 0) n = NATPMP_ERR_UNSUPPORTEDVERSION; else if(buf[1] < 128 || buf[1] > 130) n = NATPMP_ERR_UNSUPPORTEDOPCODE; else if(response->resultcode != 0) { switch(response->resultcode) { case 1: n = NATPMP_ERR_UNSUPPORTEDVERSION; break; case 2: n = NATPMP_ERR_NOTAUTHORIZED; break; case 3: n = NATPMP_ERR_NETWORKFAILURE; break; case 4: n = NATPMP_ERR_OUTOFRESOURCES; break; case 5: n = NATPMP_ERR_UNSUPPORTEDOPCODE; break; default: n = NATPMP_ERR_UNDEFINEDERROR; } } else { response->type = buf[1] & 0x7f; if(buf[1] == 128) //response->publicaddress.addr = *((uint32_t *)(buf + 8)); response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8)); else { response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8))); response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10))); response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12))); } n = 0; } } return n; } int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response) { int n; if(!p || !response) return NATPMP_ERR_INVALIDARGS; if(!p->has_pending_request) return NATPMP_ERR_NOPENDINGREQ; n = readnatpmpresponse(p, response); if(n<0) { if(n==NATPMP_TRYAGAIN) { struct timeval now; gettimeofday(&now, NULL); // check errors ! if(timercmp(&now, &p->retry_time, >=)) { int delay, r; if(p->try_number >= 9) { return NATPMP_ERR_NOGATEWAYSUPPORT; } /*printf("retry! %d\n", p->try_number);*/ delay = 250 * (1<try_number); // ms /*for(i=0; itry_number; i++) delay += delay;*/ p->retry_time.tv_sec += (delay / 1000); p->retry_time.tv_usec += (delay % 1000) * 1000; if(p->retry_time.tv_usec >= 1000000) { p->retry_time.tv_usec -= 1000000; p->retry_time.tv_sec++; } p->try_number++; r = sendpendingrequest(p); if(r<0) return r; } } } else { p->has_pending_request = 0; } return n; } #ifdef ENABLE_STRNATPMPERR LIBSPEC const char * strnatpmperr(int r) { const char * s; switch(r) { case NATPMP_ERR_INVALIDARGS: s = "invalid arguments"; break; case NATPMP_ERR_SOCKETERROR: s = "socket() failed"; break; case NATPMP_ERR_CANNOTGETGATEWAY: 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"; break; case NATPMP_ERR_NOPENDINGREQ: s = "no pending request"; break; case NATPMP_ERR_NOGATEWAYSUPPORT: s = "the gateway does not support nat-pmp"; break; case NATPMP_ERR_CONNECTERR: s = "connect() failed"; break; case NATPMP_ERR_WRONGPACKETSOURCE: s = "packet not received from the default gateway"; break; case NATPMP_ERR_SENDERR: s = "send() failed"; break; case NATPMP_ERR_FCNTLERROR: s = "fcntl() failed"; break; case NATPMP_ERR_GETTIMEOFDAYERR: s = "gettimeofday() failed"; break; case NATPMP_ERR_UNSUPPORTEDVERSION: s = "unsupported nat-pmp version error from server"; break; case NATPMP_ERR_UNSUPPORTEDOPCODE: s = "unsupported nat-pmp opcode error from server"; break; case NATPMP_ERR_UNDEFINEDERROR: s = "undefined nat-pmp server error"; break; case NATPMP_ERR_NOTAUTHORIZED: s = "not authorized"; break; case NATPMP_ERR_NETWORKFAILURE: s = "network failure"; break; case NATPMP_ERR_OUTOFRESOURCES: s = "nat-pmp server out of resources"; break; default: s = "Unknown libnatpmp error"; } return s; } #endif libnatpmp-20110808/natpmp.h010064400017500000024000000156671160777525500146350ustar00nanardstaff/* $Id: natpmp.h,v 1.15 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #ifndef __NATPMP_H__ #define __NATPMP_H__ /* NAT-PMP Port as defined by the NAT-PMP draft */ #define NATPMP_PORT (5351) #include #if !defined(_MSC_VER) #include #endif #ifdef WIN32 #include #if !defined(_MSC_VER) #include #else typedef unsigned long uint32_t; typedef unsigned short uint16_t; #endif #define in_addr_t uint32_t #include "declspec.h" #else #define LIBSPEC #include #endif typedef struct { int s; /* socket */ in_addr_t gateway; /* default gateway (IPv4) */ int has_pending_request; unsigned char pending_request[12]; int pending_request_len; int try_number; struct timeval retry_time; } natpmp_t; typedef struct { uint16_t type; /* NATPMP_RESPTYPE_* */ uint16_t resultcode; /* NAT-PMP response code */ uint32_t epoch; /* Seconds since start of epoch */ union { struct { //in_addr_t addr; struct in_addr addr; } publicaddress; struct { uint16_t privateport; uint16_t mappedpublicport; uint32_t lifetime; } newportmapping; } pnu; } natpmpresp_t; /* possible values for type field of natpmpresp_t */ #define NATPMP_RESPTYPE_PUBLICADDRESS (0) #define NATPMP_RESPTYPE_UDPPORTMAPPING (1) #define NATPMP_RESPTYPE_TCPPORTMAPPING (2) /* Values to pass to sendnewportmappingrequest() */ #define NATPMP_PROTOCOL_UDP (1) #define NATPMP_PROTOCOL_TCP (2) /* return values */ /* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */ #define NATPMP_ERR_INVALIDARGS (-1) /* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */ #define NATPMP_ERR_SOCKETERROR (-2) /* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */ #define NATPMP_ERR_CANNOTGETGATEWAY (-3) /* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */ #define NATPMP_ERR_CLOSEERR (-4) /* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */ #define NATPMP_ERR_RECVFROM (-5) /* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while * no NAT-PMP request was pending */ #define NATPMP_ERR_NOPENDINGREQ (-6) /* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */ #define NATPMP_ERR_NOGATEWAYSUPPORT (-7) /* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */ #define NATPMP_ERR_CONNECTERR (-8) /* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */ #define NATPMP_ERR_WRONGPACKETSOURCE (-9) /* NATPMP_ERR_SENDERR : send() failed. check errno for details */ #define NATPMP_ERR_SENDERR (-10) /* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */ #define NATPMP_ERR_FCNTLERROR (-11) /* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */ #define NATPMP_ERR_GETTIMEOFDAYERR (-12) /* */ #define NATPMP_ERR_UNSUPPORTEDVERSION (-14) #define NATPMP_ERR_UNSUPPORTEDOPCODE (-15) /* Errors from the server : */ #define NATPMP_ERR_UNDEFINEDERROR (-49) #define NATPMP_ERR_NOTAUTHORIZED (-51) #define NATPMP_ERR_NETWORKFAILURE (-52) #define NATPMP_ERR_OUTOFRESOURCES (-53) /* NATPMP_TRYAGAIN : no data available for the moment. try again later */ #define NATPMP_TRYAGAIN (-100) #ifdef __cplusplus extern "C" { #endif /* initnatpmp() * initialize a natpmp_t object * With forcegw=1 the gateway is not detected automaticaly. * Return values : * 0 = OK * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_SOCKETERROR * NATPMP_ERR_FCNTLERROR * NATPMP_ERR_CANNOTGETGATEWAY * NATPMP_ERR_CONNECTERR */ LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw); /* closenatpmp() * close resources associated with a natpmp_t object * Return values : * 0 = OK * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_CLOSEERR */ LIBSPEC int closenatpmp(natpmp_t * p); /* sendpublicaddressrequest() * send a public address NAT-PMP request to the network gateway * Return values : * 2 = OK (size of the request) * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_SENDERR */ LIBSPEC int sendpublicaddressrequest(natpmp_t * p); /* sendnewportmappingrequest() * send a new port mapping NAT-PMP request to the network gateway * Arguments : * protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP, * lifetime is in seconds. * To remove a port mapping, set lifetime to zero. * To remove all port mappings to the host, set lifetime and both ports * to zero. * Return values : * 12 = OK (size of the request) * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_SENDERR */ LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, uint16_t privateport, uint16_t publicport, uint32_t lifetime); /* getnatpmprequesttimeout() * fills the timeval structure with the timeout duration of the * currently pending NAT-PMP request. * Return values : * 0 = OK * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_GETTIMEOFDAYERR * NATPMP_ERR_NOPENDINGREQ */ LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout); /* readnatpmpresponseorretry() * fills the natpmpresp_t structure if possible * Return values : * 0 = OK * NATPMP_TRYAGAIN * NATPMP_ERR_INVALIDARGS * NATPMP_ERR_NOPENDINGREQ * NATPMP_ERR_NOGATEWAYSUPPORT * NATPMP_ERR_RECVFROM * NATPMP_ERR_WRONGPACKETSOURCE * NATPMP_ERR_UNSUPPORTEDVERSION * NATPMP_ERR_UNSUPPORTEDOPCODE * NATPMP_ERR_NOTAUTHORIZED * NATPMP_ERR_NETWORKFAILURE * NATPMP_ERR_OUTOFRESOURCES * NATPMP_ERR_UNSUPPORTEDOPCODE * NATPMP_ERR_UNDEFINEDERROR */ LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response); #ifdef ENABLE_STRNATPMPERR LIBSPEC const char * strnatpmperr(int t); #endif #ifdef __cplusplus } #endif #endif libnatpmp-20110808/natpmpc.c010064400017500000024000000162421160777525500147610ustar00nanardstaff/* $Id: natpmpc.c,v 1.10 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #include #include #include #if defined(_MSC_VER) #if _MSC_VER >= 1400 #define strcasecmp _stricmp #else #define strcasecmp stricmp #endif #else #include #endif #ifdef WIN32 #include #else #include #include #endif #include "natpmp.h" void usage(FILE * out, const char * argv0) { fprintf(out, "Usage :\n"); fprintf(out, " %s [options]\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 [options] -a [lifetime]\n", argv0); fprintf(out, "\tadd a port mapping.\n"); fprintf(out, "\nOption available :\n"); fprintf(out, " -g ipv4address\n"); fprintf(out, "\tforce the gateway to be used as destination for NAT-PMP commands.\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; int forcegw = 0; in_addr_t gateway = 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= 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, forcegw, gateway); printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS"); if(r<0) return 1; printf("using gateway : %s\n", inet_ntoa(*((struct in_addr *)&natpmp.gateway))); /* 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); r = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); if(r<0) { fprintf(stderr, "select()"); return 1; } 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; } libnatpmp-20110808/testgetgateway.c010064400017500000024000000040171160777525500163550ustar00nanardstaff/* $Id: testgetgateway.c,v 1.5 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #include #ifdef WIN32 #include #else #include #include #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; } libnatpmp-20110808/LICENSE010064400017500000024000000026771160777525500141670ustar00nanardstaffCopyright (c) 2007-2011, 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. libnatpmp-20110808/wingettimeofday.c010064400017500000024000000042441160777525500165150ustar00nanardstaff/* $Id: wingettimeofday.c,v 1.4 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #ifdef WIN32 #if defined(_MSC_VER) struct timeval { long tv_sec; long tv_usec; }; #else #include #endif typedef struct _FILETIME { unsigned long dwLowDateTime; unsigned long dwHighDateTime; } FILETIME; void __stdcall GetSystemTimeAsFileTime(FILETIME*); 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 libnatpmp-20110808/wingettimeofday.h010064400017500000024000000033611160777525500165210ustar00nanardstaff/* $Id: wingettimeofday.h,v 1.2 2011/07/15 08:30:11 nanard Exp $ */ /* libnatpmp Copyright (c) 2007-2011, 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. */ #ifndef __WINGETTIMEOFDAY_H__ #define __WINGETTIMEOFDAY_H__ #ifdef WIN32 #if defined(_MSC_VER) #include #else #include #endif int gettimeofday(struct timeval* p, void* tz /* IGNORED */); #endif #endif libnatpmp-20110808/natpmp.def010064400017500000024000000002741103301263300151010ustar00nanardstaffLIBRARY ; libnatpmp library EXPORTS initnatpmp closenatpmp sendpublicaddressrequest sendnewportmappingrequest getnatpmprequesttimeout readnatpmpresponseorretry strnatpmperr libnatpmp-20110808/build.bat010064400017500000024000000024131131315731100147120ustar00nanardstaff@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 libnatpmp-20110808/declspec.h010064400017500000024000000003661103300104200150470ustar00nanardstaff#ifndef __DECLSPEC_H__ #define __DECLSPEC_H__ #if defined(WIN32) && !defined(STATICLIB) #ifdef NATPMP_EXPORTS #define LIBSPEC __declspec(dllexport) #else #define LIBSPEC __declspec(dllimport) #endif #else #define LIBSPEC #endif #endif libnatpmp-20110808/libnatpmpmodule.c010064400017500000024000000167411161500240500164720ustar00nanardstaff/* $Id: libnatpmpmodule.c,v 1.6 2011/07/30 13:19:59 nanard Exp $ */ /* libnatpmp * http://miniupnp.free.fr/libnatpmp.html Copyright (c) 2007-2011, 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. */ #include #ifdef WIN32 #include #else #include #include #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, 0, 0); } 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, "HsH", &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); } libnatpmp-20110808/setup.py010064400017500000024000000007641121203720200146360ustar00nanardstaff#! /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)] )] ) libnatpmp-20110808/setupmingw32.py010064400017500000024000000007451121203720200160440ustar00nanardstaff#! /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)] )] ) libnatpmp-20110808/README010064400017500000024000000003101125344401000137730ustar00nanardstafflibnatpmp (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. libnatpmp-20110808/msvc/libnatpmp.sln010064400017500000024000000027071131314010000165710ustar00nanardstaff 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 libnatpmp-20110808/msvc/libnatpmp.vcproj010064400017500000024000000072321131314010000172760ustar00nanardstaff libnatpmp-20110808/msvc/natpmpc-static.vcproj010064400017500000024000000075671131315731100202660ustar00nanardstaff libnatpmp-20110808/natpmpc.1010064400017500000024000000006351157675575300147040ustar00nanardstaff.TH natpmpc 1 .SH NAME natpmpc \- NAT\-PMP library test client and mapping setter. .SH "SYNOPSIS" Display the public IP address: .br \fBnatpmpc\fP Add a port mapping: .br \fBnatpmpc\fP \-a [lifetime] .SH DESCRIPTION In order to remove a mapping, set it with a lifetime of 0 seconds. To remove all mappings for your machine, use 0 as private port and lifetime.