From 75bf71e92c81b966df11ad3c00228658f46a6e8f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 1 Sep 2010 13:36:01 +0000 Subject: starting NAT code cleanup --- configure.ac | 2 - src/include/gnunet_nat_lib.h | 52 +-- src/nat/Makefile.am | 12 +- src/nat/libnatpmp/Makefile.am | 16 - src/nat/libnatpmp/README | 4 - src/nat/libnatpmp/declspec.h | 14 - src/nat/libnatpmp/getgateway.c | 531 --------------------- src/nat/libnatpmp/getgateway.h | 32 -- src/nat/libnatpmp/natpmp.c | 409 ---------------- src/nat/libnatpmp/natpmp.h | 202 -------- src/nat/miniupnp/Makefile.am | 31 -- src/nat/miniupnp/README | 3 - src/nat/miniupnp/bsdqueue.h | 531 --------------------- src/nat/miniupnp/codelength.h | 23 - src/nat/miniupnp/declspec.h | 14 - src/nat/miniupnp/igd_desc_parse.c | 126 ----- src/nat/miniupnp/igd_desc_parse.h | 47 -- src/nat/miniupnp/minisoap.c | 106 ----- src/nat/miniupnp/minisoap.h | 14 - src/nat/miniupnp/minissdpc.c | 111 ----- src/nat/miniupnp/minissdpc.h | 14 - src/nat/miniupnp/miniupnpc.c | 901 ------------------------------------ src/nat/miniupnp/miniupnpc.h | 120 ----- src/nat/miniupnp/miniupnpcstrings.h | 14 - src/nat/miniupnp/miniwget.c | 224 --------- src/nat/miniupnp/miniwget.h | 28 -- src/nat/miniupnp/minixml.c | 200 -------- src/nat/miniupnp/minixml.h | 37 -- src/nat/miniupnp/upnpcommands.c | 605 ------------------------ src/nat/miniupnp/upnpcommands.h | 189 -------- src/nat/miniupnp/upnpreplyparse.c | 122 ----- src/nat/miniupnp/upnpreplyparse.h | 60 --- src/nat/nat.c | 293 ++++++------ src/nat/natpmp.h | 17 +- src/nat/upnp.c | 27 +- src/nat/upnp.h | 21 +- 36 files changed, 217 insertions(+), 4935 deletions(-) delete mode 100644 src/nat/libnatpmp/Makefile.am delete mode 100644 src/nat/libnatpmp/README delete mode 100644 src/nat/libnatpmp/declspec.h delete mode 100644 src/nat/libnatpmp/getgateway.c delete mode 100644 src/nat/libnatpmp/getgateway.h delete mode 100644 src/nat/libnatpmp/natpmp.c delete mode 100644 src/nat/libnatpmp/natpmp.h delete mode 100644 src/nat/miniupnp/Makefile.am delete mode 100644 src/nat/miniupnp/README delete mode 100644 src/nat/miniupnp/bsdqueue.h delete mode 100644 src/nat/miniupnp/codelength.h delete mode 100644 src/nat/miniupnp/declspec.h delete mode 100644 src/nat/miniupnp/igd_desc_parse.c delete mode 100644 src/nat/miniupnp/igd_desc_parse.h delete mode 100644 src/nat/miniupnp/minisoap.c delete mode 100644 src/nat/miniupnp/minisoap.h delete mode 100644 src/nat/miniupnp/minissdpc.c delete mode 100644 src/nat/miniupnp/minissdpc.h delete mode 100644 src/nat/miniupnp/miniupnpc.c delete mode 100644 src/nat/miniupnp/miniupnpc.h delete mode 100644 src/nat/miniupnp/miniupnpcstrings.h delete mode 100644 src/nat/miniupnp/miniwget.c delete mode 100644 src/nat/miniupnp/miniwget.h delete mode 100644 src/nat/miniupnp/minixml.c delete mode 100644 src/nat/miniupnp/minixml.h delete mode 100644 src/nat/miniupnp/upnpcommands.c delete mode 100644 src/nat/miniupnp/upnpcommands.h delete mode 100644 src/nat/miniupnp/upnpreplyparse.c delete mode 100644 src/nat/miniupnp/upnpreplyparse.h diff --git a/configure.ac b/configure.ac index 8742605d2..22133e07d 100644 --- a/configure.ac +++ b/configure.ac @@ -753,8 +753,6 @@ src/include/gnunet_directories.h src/hostlist/Makefile src/monkey/Makefile src/nat/Makefile -src/nat/libnatpmp/Makefile -src/nat/miniupnp/Makefile src/peerinfo/Makefile src/peerinfo-tool/Makefile src/statistics/Makefile diff --git a/src/include/gnunet_nat_lib.h b/src/include/gnunet_nat_lib.h index 868edbee1..9c6e171b6 100644 --- a/src/include/gnunet_nat_lib.h +++ b/src/include/gnunet_nat_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2007, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -27,28 +27,9 @@ */ #ifndef GNUNET_NAT_LIB_H -#define GNUNET_NAT_LIB_H 1 +#define GNUNET_NAT_LIB_H -#include "platform.h" #include "gnunet_util_lib.h" -#include "upnp.h" -#include "natpmp.h" - -#include - -/** - * Used to communicate with the UPnP and NAT-PMP plugins - * FIXME: move to src/nat/common.h - */ -enum GNUNET_NAT_port_forwarding - { - GNUNET_NAT_PORT_ERROR, - GNUNET_NAT_PORT_UNMAPPED, - GNUNET_NAT_PORT_UNMAPPING, - GNUNET_NAT_PORT_MAPPING, - GNUNET_NAT_PORT_MAPPED - }; - /** * Signature of the callback passed to GNUNET_NAT_register. @@ -59,10 +40,12 @@ enum GNUNET_NAT_port_forwarding * @param addr either the previous or the new public IP address * @param addrlen actual lenght of the address */ -typedef void (*GNUNET_NAT_AddressCallback) (void *cls, int add_remove, +typedef void (*GNUNET_NAT_AddressCallback) (void *cls, + int add_remove, const struct sockaddr * addr, socklen_t addrlen); + /** * Handle for active NAT registrations. */ @@ -81,12 +64,13 @@ struct GNUNET_NAT_Handle; * @param callback_cls closure for callback * @return NULL on error, otherwise handle that can be used to unregister */ -struct GNUNET_NAT_Handle *GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle - *sched, - const struct sockaddr *addr, - socklen_t addrlen, - GNUNET_NAT_AddressCallback - callback, void *callback_cls); +struct GNUNET_NAT_Handle * +GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, + const struct sockaddr *addr, + socklen_t addrlen, + GNUNET_NAT_AddressCallback callback, + void *callback_cls); + /** * Stop port redirection and public IP address detection for the given handle. @@ -96,18 +80,6 @@ struct GNUNET_NAT_Handle *GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle */ void GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h); -/** - * Compare the sin(6)_addr fields of AF_INET or AF_INET(6) sockaddr. - * FIXME: move to src/nat/common.h or so. - * - * @param a first sockaddr - * @param b second sockaddr - * @return 0 if addresses are equal, non-null value otherwise - */ -int GNUNET_NAT_cmp_addr (const struct sockaddr *a, - const struct sockaddr *b); - - #endif /* end of gnunet_nat_lib.h */ diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am index 14a4d4e92..c47348b7c 100644 --- a/src/nat/Makefile.am +++ b/src/nat/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = miniupnp libnatpmp +SUBDIRS = . INCLUDES = -I$(top_srcdir)/src/include @@ -12,7 +12,9 @@ endif if !MINGW +if HAVE_EXPERIMENTAL lib_LTLIBRARIES = libgnunetnat.la +endif libgnunetnat_la_SOURCES = \ upnp.c upnp.h \ @@ -24,16 +26,16 @@ libgnunetnat_la_CFLAGS = \ libgnunetnat_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/nat/miniupnp/libminiupnp.la \ - $(top_builddir)/src/nat/libnatpmp/libnatpmp.la \ - $(GN_LIBINTL) @EXT_LIBS@ + $(GN_LIBINTL) @EXT_LIBS@ libgnunetnat_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ -version-info 0:0:0 +if HAVE_EXPERIMENTAL check_PROGRAMS = \ test-nat +endif if !DISABLE_TEST_RUN TESTS = $(check_PROGRAMS) @@ -46,4 +48,4 @@ test_nat_LDADD = \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -endif \ No newline at end of file +endif diff --git a/src/nat/libnatpmp/Makefile.am b/src/nat/libnatpmp/Makefile.am deleted file mode 100644 index 472bcabae..000000000 --- a/src/nat/libnatpmp/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -noinst_LTLIBRARIES = libnatpmp.la - -AM_CPPFLAGS = -DENABLE_STRNATPMPERR - -libnatpmp_la_SOURCES = \ - getgateway.c \ - natpmp.c - -noinst_HEADERS = \ - declspec.h \ - getgateway.h \ - natpmp.h - -extra_DIST = \ - README \ - LICENSE diff --git a/src/nat/libnatpmp/README b/src/nat/libnatpmp/README deleted file mode 100644 index 50fdd1093..000000000 --- a/src/nat/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/src/nat/libnatpmp/declspec.h b/src/nat/libnatpmp/declspec.h deleted file mode 100644 index 6c817977a..000000000 --- a/src/nat/libnatpmp/declspec.h +++ /dev/null @@ -1,14 +0,0 @@ -#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 diff --git a/src/nat/libnatpmp/getgateway.c b/src/nat/libnatpmp/getgateway.c deleted file mode 100644 index d948669ec..000000000 --- a/src/nat/libnatpmp/getgateway.c +++ /dev/null @@ -1,531 +0,0 @@ -/* $Id: getgateway.c,v 1.13 2009/03/10 10:15:31 nanard Exp $ */ -/* libnatpmp - * Copyright (c) 2007-2008, Thomas BERNARD - * - * 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 -#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. - * 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. */ -#ifdef __linux__ -#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_PROC_NET_ROUTE -#include -#endif -#ifdef USE_SYSCTL_NET_ROUTE -#include -#include -#include -#include -#endif -#ifdef USE_SOCKET_ROUTE -#include -#include -#include -#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 (int *af, uint8_t addr[16]) -{ - unsigned int tmp; - uint8_t d[16]; - char buf[256]; - int line = 0; - FILE *f; - char *p; - int i; - f = fopen ("/proc/net/route", "r"); - if (!f) - return FAILED; - while (fgets (buf, sizeof (buf), f)) - { - if (line > 0) - { - p = buf; - while (*p && !isspace ( (unsigned char) *p)) - p++; - while (*p && isspace ( (unsigned char) *p)) - p++; - for (i = 0; i < 16; i++) - { - if (sscanf (p, "%2X", &tmp) < 1) - d[i] = tmp; - else - break; - } - - if (i == 8) /* IPv4 address on 8 hex chars */ - { - /* Move the 32 bits address to the end of the array */ - for (i = 4; i < 16; i++) - d[i] = 0; - - for (i = 0; i < 4; i++) - { - d[i+12] = d[i]; - d[i] = 0; - } - memcpy (addr, d, 16 * sizeof (uint8_t)); - *af = AF_INET; - fclose (f); - return SUCCESS; - } - else if (i == 16) /* IPv6 address on 16 hex chars, - * or IPv4 address padded with 0 */ - { - memcpy (addr, d, 16 * sizeof (uint8_t)); - /* Check at what byte the actual address starts */ - for (i = 0; i <= 12; i++) - if (addr[i]) break; - - if (i == 12) - { - *af = AF_INET; - fclose (f); - return SUCCESS; - } - else if (i == 0) - { - *af = AF_INET6; - 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 (int *af, uint8_t addr[16]) -{ -#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; p < buf + l; p += rt->rtm_msglen) - { - rt = (struct rt_msghdr *) p; - sa = (struct sockaddr *) (rt + 1); - for (i = 0; i < RTAX_MAX; i++) - { - if (rt->rtm_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; - *af = AF_INET; - r = SUCCESS; - } - } - else if (((rt->rtm_addrs & (RTA_DST | RTA_GATEWAY)) == - (RTA_DST | RTA_GATEWAY)) - && sa_tab[RTAX_DST]->sa_family == AF_INET6 - && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET6) - { - if (IN6_IS_ADDR_UNSPECIFIED (&(((struct sockaddr_in6 *) - sa_tab[RTAX_DST])->sin6_addr))) - { - *(struct in6_addr *)addr = - ((struct sockaddr_in6 *) (sa_tab[RTAX_GATEWAY]))->sin6_addr; - *af = AF_INET6; - 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 (int *af, uint8_t addr[16]) -{ - 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 && gate->sa_family == AF_INET) - { - *addr = ((struct sockaddr_in *) gate)->sin_addr.s_addr; - *af = AF_INET; - return SUCCESS; - } - else if (gate != NULL && gate->sa_family == AF_INET6) - { - memcpy (addr, ((struct sockaddr_in6 *) gate)->sin6_addr.s6_addr, 16 * sizeof (uint8_t)); - *af = AF_INET6; - return SUCCESS; - } - else - { - return FAILED; - } -} -#endif /* #ifdef USE_SOCKET_ROUTE */ - -#ifdef USE_WIN32_CODE -int -getdefaultgateway (int *af, uint8_t addr[16]) -{ - 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; - } - } - else if (ERROR_SUCCESS == RegQueryValueEx (interfaceKey, // Open registry key - "DefaultGateway", // 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/src/nat/libnatpmp/getgateway.h b/src/nat/libnatpmp/getgateway.h deleted file mode 100644 index 35dc1e93a..000000000 --- a/src/nat/libnatpmp/getgateway.h +++ /dev/null @@ -1,32 +0,0 @@ -/* $Id: getgateway.h,v 1.3 2008/07/02 22:33:06 nanard Exp $ */ -/* libnatpmp - * Copyright (c) 2007, Thomas BERNARD - * - * 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 __GETGATEWAY_H__ -#define __GETGATEWAY_H__ - -#ifdef WIN32 -#include -#define in_addr_t uint32_t -#endif -#include "declspec.h" - -/* getdefaultgateway() : - * addr must point to an array of at least 16 u_int8 elements - * return value : - * 0 : success - * -1 : failure */ -LIBSPEC int getdefaultgateway (int *af, uint8_t addr[16]); - -#endif diff --git a/src/nat/libnatpmp/natpmp.c b/src/nat/libnatpmp/natpmp.c deleted file mode 100644 index 12526df8e..000000000 --- a/src/nat/libnatpmp/natpmp.c +++ /dev/null @@ -1,409 +0,0 @@ -/* $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 - * - * 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 -#include -#include -#ifdef WIN32 -#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 - int domain = AF_INET; - int gw_domain; - struct sockaddr_in addr; - struct sockaddr_in6 addr6; - - if (!p) - return NATPMP_ERR_INVALIDARGS; - - if (p->addr) - domain = (p->addr->sa_family == AF_INET) ? PF_INET : PF_INET6; - - memset (p, 0, sizeof (natpmp_t)); - p->s = socket (domain, SOCK_DGRAM, 0); - if (p->s < 0) - return NATPMP_ERR_SOCKETERROR; - /* If addr has been set, use it, else get the default from connect() */ - if (p->addr && bind (p->s, p->addr, p->addrlen) < 0) - return NATPMP_ERR_BINDERROR; -#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 (&gw_domain, p->gateway) < 0) - return NATPMP_ERR_CANNOTGETGATEWAY; - - if (domain != gw_domain) - return NATPMP_ERR_ADDRERROR; - - if (domain == AF_INET) - { - memset (&addr, 0, sizeof (addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons (NATPMP_PORT); - memcpy (&addr.sin_addr.s_addr, p->gateway, 4 * sizeof (uint8_t)); -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - addr.sin_len = sizeof (addr); -#endif - if (connect (p->s, (struct sockaddr *) &addr, sizeof (addr)) < 0) - return NATPMP_ERR_CONNECTERR; - } - else - { - memset (&addr6, 0, sizeof (addr6)); - addr6.sin6_family = AF_INET6; - addr6.sin6_port = htons (NATPMP_PORT); - memcpy (addr6.sin6_addr.s6_addr, p->gateway, 16 * sizeof (uint8_t)); -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - addr6.sin6_len = sizeof (addr6); -#endif - if (connect (p->s, (struct sockaddr *) &addr6, sizeof (addr6)) < 0) - return NATPMP_ERR_CONNECTERR; - } - - return 0; -} - -int -closenatpmp (natpmp_t * p) -{ - if (!p) - return NATPMP_ERR_INVALIDARGS; - if (closesocket (p->s) < 0) - return NATPMP_ERR_CLOSEERR; - return 0; -} - -static 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; -} - -static 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; -} - -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; -} - -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); -} - -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); -} - -static int -readnatpmpresponse (natpmp_t * p, natpmpresp_t * response) -{ - unsigned char buf[16]; - struct sockaddr_storage 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.ss_family == AF_INET && memcmp (&((struct sockaddr_in *) &addr)->sin_addr.s_addr, p->gateway, 4 * sizeof (uint8_t)) == 0) - n = NATPMP_ERR_WRONGPACKETSOURCE; - else if (addr.ss_family == AF_INET6 && memcmp (((struct sockaddr_in6 *) &addr)->sin6_addr.s6_addr, p->gateway, 16 * sizeof (uint8_t)) == 0) - 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->pnu.publicaddress.family = AF_INET; - memset (&response->pnu.publicaddress.addr6.s6_addr, 0, sizeof (struct in6_addr)); - response->pnu.publicaddress.addr.s_addr = - *((uint32_t *) (buf + 8)); - /* FIXME: support IPv6 address */ - } - 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 << p->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 -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 diff --git a/src/nat/libnatpmp/natpmp.h b/src/nat/libnatpmp/natpmp.h deleted file mode 100644 index 976bad06f..000000000 --- a/src/nat/libnatpmp/natpmp.h +++ /dev/null @@ -1,202 +0,0 @@ -/* $Id: natpmp.h,v 1.11 2009/02/27 22:38:05 nanard Exp $ */ -/* libnatpmp - * Copyright (c) 2007-2008, Thomas BERNARD - * 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 __NATPMP_H__ -#define __NATPMP_H__ - -/* NAT-PMP Port as defined by the NAT-PMP draft */ -#define NATPMP_PORT (5351) - -#include -#include -#include -#ifdef WIN32 -#include -#include -#define in_addr_t uint32_t -#include "declspec.h" -#else -#define LIBSPEC -#include -#include -#endif - -typedef struct -{ - int s; /* socket */ - struct sockaddr *addr; - socklen_t addrlen; - uint8_t gateway[16]; /* default gateway (IPv4 or IPv6) */ - 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 - { - int family; - struct in_addr addr; - struct in6_addr addr6; - } 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) -/* NATPMP_ERR_BINDERROR : bind() failed. check errno for details */ -#define NATPMP_ERR_BINDERROR (-13) -/* NATPMP_ERR_ADDRERROR : gateway does not use the same inet protocol as the passed address */ -#define NATPMP_ERR_ADDRERROR (-14) - -/* */ -#define NATPMP_ERR_UNSUPPORTEDVERSION (-15) -#define NATPMP_ERR_UNSUPPORTEDOPCODE (-16) - -/* 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) - -/* initnatpmp() - * initialize a natpmp_t object - * 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); - -/* 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 - -#endif diff --git a/src/nat/miniupnp/Makefile.am b/src/nat/miniupnp/Makefile.am deleted file mode 100644 index 731c41a84..000000000 --- a/src/nat/miniupnp/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -noinst_LTLIBRARIES = libminiupnp.la - -AM_CPPFLAGS = -DNDEBUG - -libminiupnp_la_SOURCES = \ - igd_desc_parse.c \ - minisoap.c \ - minissdpc.c \ - miniupnpc.c \ - miniwget.c \ - minixml.c \ - upnpcommands.c \ - upnpreplyparse.c - -noinst_HEADERS = \ - bsdqueue.h \ - codelength.h \ - declspec.h \ - igd_desc_parse.h \ - minisoap.h \ - minissdpc.h \ - miniupnpc.h \ - miniupnpcstrings.h \ - miniwget.h \ - minixml.h \ - upnpcommands.h \ - upnpreplyparse.h - -extra_DIST = \ - README \ - LICENSE diff --git a/src/nat/miniupnp/README b/src/nat/miniupnp/README deleted file mode 100644 index 45aec9084..000000000 --- a/src/nat/miniupnp/README +++ /dev/null @@ -1,3 +0,0 @@ -MiniUPnP is written by Thomas Bernard. -Its homepage is http://miniupnp.free.fr/ -This is from miniupnpc-1.3.tar.gz diff --git a/src/nat/miniupnp/bsdqueue.h b/src/nat/miniupnp/bsdqueue.h deleted file mode 100644 index f763172c4..000000000 --- a/src/nat/miniupnp/bsdqueue.h +++ /dev/null @@ -1,531 +0,0 @@ -/* $OpenBSD: queue.h,v 1.31 2005/11/25 08:06:25 otto Exp $ */ -/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues, and circular queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -#ifdef QUEUE_MACRO_DEBUG -#define _Q_INVALIDATE(a) (a) = ((void *)-1) -#else -#define _Q_INVALIDATE(a) -#endif - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#ifdef SLIST_ENTRY -#undef SLIST_ENTRY -#endif - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = SLIST_FIRST(head); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT(var, field)) - -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != SLIST_END(head); \ - (varp) = &SLIST_NEXT((var), field)) - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) { \ - SLIST_FIRST(head) = SLIST_END(head); \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_REMOVE_NEXT(head, elm, field) do { \ - (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->slh_first; \ - \ - while (curelm->field.sle_next != (elm)) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - _Q_INVALIDATE((elm)->field.sle_next); \ - } \ -} while (0) - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_FOREACH(var, head, field) \ - for((var) = LIST_FIRST(head); \ - (var)!= LIST_END(head); \ - (var) = LIST_NEXT(var, field)) - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST(head) = LIST_END(head); \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -#define LIST_REPLACE(elm, elm2, field) do { \ - if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ - (elm2)->field.le_next->field.le_prev = \ - &(elm2)->field.le_next; \ - (elm2)->field.le_prev = (elm)->field.le_prev; \ - *(elm2)->field.le_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -/* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for((var) = SIMPLEQ_FIRST(head); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT(var, field)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (0) - -#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * tail queue access methods - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) \ - (TAILQ_FIRST(head) == TAILQ_END(head)) - -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV(var, headname, field)) - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -#define TAILQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ - (elm2)->field.tqe_next->field.tqe_prev = \ - &(elm2)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm2)->field.tqe_next; \ - (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ - *(elm2)->field.tqe_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue access methods - */ -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -#define CIRCLEQ_END(head) ((void *)(head)) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) -#define CIRCLEQ_EMPTY(head) \ - (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = CIRCLEQ_FIRST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_NEXT(var, field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for((var) = CIRCLEQ_LAST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_PREV(var, field)) - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = CIRCLEQ_END(head); \ - (head)->cqh_last = CIRCLEQ_END(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = CIRCLEQ_END(head); \ - if ((head)->cqh_last == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = CIRCLEQ_END(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ - _Q_INVALIDATE((elm)->field.cqe_prev); \ - _Q_INVALIDATE((elm)->field.cqe_next); \ -} while (0) - -#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ - CIRCLEQ_END(head)) \ - (head).cqh_last = (elm2); \ - else \ - (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ - if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ - CIRCLEQ_END(head)) \ - (head).cqh_first = (elm2); \ - else \ - (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ - _Q_INVALIDATE((elm)->field.cqe_prev); \ - _Q_INVALIDATE((elm)->field.cqe_next); \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/src/nat/miniupnp/codelength.h b/src/nat/miniupnp/codelength.h deleted file mode 100644 index 8a5f49517..000000000 --- a/src/nat/miniupnp/codelength.h +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: codelength.h,v 1.1 2008/10/06 22:04:06 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2005-2008 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#ifndef __CODELENGTH_H__ -#define __CODELENGTH_H__ - -/* Encode length by using 7bit per Byte : - * Most significant bit of each byte specifies that the - * following byte is part of the code */ -#define DECODELENGTH(n, p) n = 0; \ - do { n = (n << 7) | (*p & 0x7f); } \ - while(*(p++)&0x80); - -#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ - if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ - if(n>=16384) *(p++) = (n >> 14) | 0x80; \ - if(n>=128) *(p++) = (n >> 7) | 0x80; \ - *(p++) = n & 0x7f; - -#endif diff --git a/src/nat/miniupnp/declspec.h b/src/nat/miniupnp/declspec.h deleted file mode 100644 index c064bded2..000000000 --- a/src/nat/miniupnp/declspec.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __DECLSPEC_H__ -#define __DECLSPEC_H__ - -#if defined(WIN32) && !defined(STATICLIB) -#ifdef MINIUPNP_EXPORTS -#define LIBSPEC __declspec(dllexport) -#else -#define LIBSPEC __declspec(dllimport) -#endif -#else -#define LIBSPEC -#endif - -#endif diff --git a/src/nat/miniupnp/igd_desc_parse.c b/src/nat/miniupnp/igd_desc_parse.c deleted file mode 100644 index deb53152c..000000000 --- a/src/nat/miniupnp/igd_desc_parse.c +++ /dev/null @@ -1,126 +0,0 @@ -/* $Id: igd_desc_parse.c,v 1.8 2008/04/23 11:51:06 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#include "igd_desc_parse.h" -#include -#include - -/* 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) -{ - struct IGDdatas *datas = (struct IGDdatas *) d; - memcpy (datas->cureltname, name, 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'; - } -} - -/* End element handler : - * update nesting level counter and update parser state if - * service element is parsed */ -void -IGDendelt (void *d, const char *name, int l) -{ - struct IGDdatas *datas = (struct IGDdatas *) d; - datas->level--; - /*printf("endelt %2d %.*s\n", datas->level, l, name); */ - if ((l == 7) && !memcmp (name, "service", l)) - { - /* - if( datas->state < 1 - && !strcmp(datas->servicetype, - // "urn:schemas-upnp-org:service:WANIPConnection:1") ) - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) - datas->state ++; - */ - if (0 == strcmp (datas->servicetype_tmp, - "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, - "urn:schemas-upnp-org:service:WANIPConnection:1") - || 0 == strcmp (datas->servicetype_tmp, - "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); - } - } -} - -/* Data handler : - * copy data depending on the current element name and state */ -void -IGDdata (void *d, const char *data, int l) -{ - struct IGDdatas *datas = (struct IGDdatas *) d; - char *dstmember = 0; - /*printf("%2d %s : %.*s\n", - datas->level, datas->cureltname, l, data); */ - if (!strcmp (datas->cureltname, "URLBase")) - dstmember = datas->urlbase; - else if (!strcmp (datas->cureltname, "serviceType")) - dstmember = datas->servicetype_tmp; - else if (!strcmp (datas->cureltname, "controlURL")) - dstmember = datas->controlurl_tmp; - else if (!strcmp (datas->cureltname, "eventSubURL")) - dstmember = datas->eventsuburl_tmp; - else if (!strcmp (datas->cureltname, "SCPDURL")) - dstmember = datas->scpdurl_tmp; -/* else if( !strcmp(datas->cureltname, "deviceType") ) - dstmember = datas->devicetype_tmp;*/ - if (dstmember) - { - if (l >= MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE - 1; - memcpy (dstmember, data, l); - dstmember[l] = '\0'; - } -} - -void -printIGD (struct IGDdatas *d) -{ - 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 ("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); -} diff --git a/src/nat/miniupnp/igd_desc_parse.h b/src/nat/miniupnp/igd_desc_parse.h deleted file mode 100644 index 5e7e24b86..000000000 --- a/src/nat/miniupnp/igd_desc_parse.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $Id: igd_desc_parse.h,v 1.6 2008/04/23 11:51:07 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef __IGD_DESC_PARSE_H__ -#define __IGD_DESC_PARSE_H__ - -/* Structure to store the result of the parsing of UPnP - * descriptions of Internet Gateway Devices */ -#define MINIUPNPC_URL_MAXSIZE (128) -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]; */ - /* "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]; */ - /* 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]; */ -}; - -void IGDstartelt (void *, const char *, int); -void IGDendelt (void *, const char *, int); -void IGDdata (void *, const char *, int); -void printIGD (struct IGDdatas *); - -#endif diff --git a/src/nat/miniupnp/minisoap.c b/src/nat/miniupnp/minisoap.c deleted file mode 100644 index a020f9a64..000000000 --- a/src/nat/miniupnp/minisoap.c +++ /dev/null @@ -1,106 +0,0 @@ -/* $Id: minisoap.c,v 1.16 2008/10/11 16:39:29 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * - * Minimal SOAP implementation for UPnP protocol. - */ -#include -#include -#ifdef WIN32 -#include -#include -#define snprintf _snprintf -#else -#include -#include -#include -#endif -#include "minisoap.h" -#include "miniupnpcstrings.h" - -/* only for malloc */ -#include - -#ifdef WIN32 -#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -/* httpWrite sends the headers and the body to the socket - * and returns the number of bytes sent */ -static int -httpWrite (int fd, const char *body, int bodysize, - const char *headers, int headerssize) -{ - int n = 0; - /*n = write(fd, headers, headerssize); */ - /*if(bodysize>0) - n += write(fd, body, bodysize); */ - /* Note : my old linksys router only took into account - * soap request that are sent into only one packet */ - char *p; - /* TODO: AVOID MALLOC */ - p = malloc (headerssize + bodysize); - if (!p) - return 0; - memcpy (p, headers, headerssize); - memcpy (p + headerssize, body, bodysize); - /*n = write(fd, p, headerssize+bodysize); */ - n = send (fd, p, headerssize + bodysize, 0); - if (n < 0) - { - PRINT_SOCKET_ERROR ("send"); - } - /* disable send on the socket */ - /* draytek routers dont seems to like that... */ -#if 0 -#ifdef WIN32 - if (shutdown (fd, SD_SEND) < 0) - { -#else - if (shutdown (fd, SHUT_WR) < 0) - { /*SD_SEND */ -#endif - PRINT_SOCKET_ERROR ("shutdown"); - } -#endif - free (p); - return n; -} - -/* self explanatory */ -int -soapPostSubmit (int fd, - const char *url, - const char *host, - unsigned short port, const char *action, const char *body) -{ - int bodysize; - char headerbuf[512]; - int headerssize; - char portstr[8]; - 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 */ - /* 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"*/ - "Host: %s%s\r\n" "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" "Content-Length: %d\r\n" "Content-Type: text/xml\r\n" "SOAPAction: \"%s\"\r\n" "Connection: Close\r\n" "Cache-Control: no-cache\r\n" /* ??? */ - "Pragma: no-cache\r\n" - "\r\n", url, host, portstr, bodysize, action); -#ifdef DEBUG - printf ("SOAP request : headersize=%d bodysize=%d\n", - headerssize, bodysize); - /*printf("%s", headerbuf); */ -#endif - return httpWrite (fd, body, bodysize, headerbuf, headerssize); -} diff --git a/src/nat/miniupnp/minisoap.h b/src/nat/miniupnp/minisoap.h deleted file mode 100644 index 2505e4c20..000000000 --- a/src/nat/miniupnp/minisoap.h +++ /dev/null @@ -1,14 +0,0 @@ -/* $Id: minisoap.h,v 1.3 2006/11/19 22:32:34 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ -#ifndef __MINISOAP_H__ -#define __MINISOAP_H__ - -/*int httpWrite(int, const char *, int, const char *);*/ -int soapPostSubmit (int, const char *, const char *, unsigned short, - const char *, const char *); - -#endif diff --git a/src/nat/miniupnp/minissdpc.c b/src/nat/miniupnp/minissdpc.c deleted file mode 100644 index 3fe89ef94..000000000 --- a/src/nat/miniupnp/minissdpc.c +++ /dev/null @@ -1,111 +0,0 @@ -/* $Id: minissdpc.c,v 1.7 2008/12/18 17:45:48 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2005-2008 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -/*#include */ -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#include -#include -#else -#include -#include -#endif - -#include "minissdpc.h" -#include "miniupnpc.h" - -#include "codelength.h" - -struct UPNPDev * -getDevicesFromMiniSSDPD (const char *devtype, const char *socketpath) -{ - struct UPNPDev *tmp; - struct UPNPDev *devlist = NULL; - unsigned char buffer[2048]; - ssize_t n; - unsigned char *p; - unsigned char *url; - unsigned int i; - unsigned int urlsize, stsize, usnsize, l; - int s; - struct sockaddr_un addr; - - s = socket (AF_UNIX, SOCK_STREAM, 0); - if (s < 0) - { - /*syslog(LOG_ERR, "socket(unix): %m"); */ - perror ("socket(unix)"); - return NULL; - } - addr.sun_family = AF_UNIX; - strncpy (addr.sun_path, socketpath, sizeof (addr.sun_path)); - if (connect (s, (struct sockaddr *) &addr, sizeof (struct sockaddr_un)) < 0) - { - /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath); */ - close (s); - return NULL; - } - stsize = strlen (devtype); - buffer[0] = 1; /* request type 1 : request devices/services by type */ - p = buffer + 1; - l = stsize; - CODELENGTH (l, p); - memcpy (p, devtype, stsize); - p += stsize; - if (write (s, buffer, p - buffer) < 0) - { - /*syslog(LOG_ERR, "write(): %m"); */ - perror ("minissdpc.c: write()"); - close (s); - return NULL; - } - n = read (s, buffer, sizeof (buffer)); - if (n <= 0) - { - perror ("minissdpc.c: read()"); - close (s); - return NULL; - } - p = buffer + 1; - for (i = 0; i < buffer[0]; i++) - { - if (p + 2 >= buffer + sizeof (buffer)) - break; - DECODELENGTH (urlsize, p); - if (p + urlsize + 2 >= buffer + sizeof (buffer)) - break; - url = p; - p += urlsize; - DECODELENGTH (stsize, p); - if (p + stsize + 2 >= buffer + sizeof (buffer)) - break; - tmp = - (struct UPNPDev *) malloc (sizeof (struct UPNPDev) + urlsize + - stsize); - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - memcpy (tmp->buffer, url, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy (tmp->buffer + urlsize + 1, p, stsize); - p += stsize; - tmp->buffer[urlsize + 1 + stsize] = '\0'; - devlist = tmp; - /* added for compatibility with recent versions of MiniSSDPd - * >= 2007/12/19 */ - DECODELENGTH (usnsize, p); - p += usnsize; - if (p > buffer + sizeof (buffer)) - break; - } - close (s); - return devlist; -} diff --git a/src/nat/miniupnp/minissdpc.h b/src/nat/miniupnp/minissdpc.h deleted file mode 100644 index f6c7db547..000000000 --- a/src/nat/miniupnp/minissdpc.h +++ /dev/null @@ -1,14 +0,0 @@ -/* $Id: minissdpc.h,v 1.1 2007/08/31 15:15:33 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2007 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef __MINISSDPC_H__ -#define __MINISSDPC_H__ - -struct UPNPDev *getDevicesFromMiniSSDPD (const char *devtype, - const char *socketpath); - -#endif diff --git a/src/nat/miniupnp/miniupnpc.c b/src/nat/miniupnp/miniupnpc.c deleted file mode 100644 index 34bae0ad8..000000000 --- a/src/nat/miniupnp/miniupnpc.c +++ /dev/null @@ -1,901 +0,0 @@ -/* $Id: miniupnpc.c,v 1.57 2008/12/18 17:46:36 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2005-2007 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#include -#include -#ifdef WIN32 -/* Win32 Specific includes and defines */ -#include -#include -#include -#include -#define snprintf _snprintf -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else -#define strncasecmp memicmp -#endif -#define MAXHOSTNAMELEN 64 -#else -/* Standard POSIX includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define closesocket close -#endif -#include "miniupnpc.h" -#include "minissdpc.h" -#include "miniwget.h" -#include "minisoap.h" -#include "minixml.h" -#include "upnpcommands.h" - -#ifdef WIN32 -#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#define SOAPPREFIX "s" -#define SERVICEPREFIX "u" -#define SERVICEPREFIX2 'u' - -/* root description parsing */ -void -parserootdesc (const char *buffer, int bufsize, struct IGDdatas *data) -{ - struct xmlparser parser; - /* xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = IGDstartelt; - parser.endeltfunc = IGDendelt; - parser.datafunc = IGDdata; - parser.attfunc = 0; - parsexml (&parser); -#ifdef DEBUG - printIGD (data); -#endif -} - -/* Content-length: nnn */ -static int -getcontentlenfromline (const char *p, int n) -{ - static const char contlenstr[] = "content-length"; - const char *p2 = contlenstr; - int a = 0; - while (*p2) - { - if (n == 0) - return -1; - if (*p2 != *p && *p2 != (*p + 32)) - return -1; - p++; - p2++; - n--; - } - if (n == 0) - return -1; - if (*p != ':') - return -1; - p++; - n--; - while (*p == ' ') - { - if (n == 0) - return -1; - p++; - n--; - } - while (*p >= '0' && *p <= '9') - { - if (n == 0) - return -1; - a = (a * 10) + (*p - '0'); - p++; - n--; - } - return a; -} - -static void -getContentLengthAndHeaderLength (char *p, int n, - int *contentlen, int *headerlen) -{ - char *line; - int linelen; - int r; - line = p; - while (line < p + n) - { - linelen = 0; - while (line[linelen] != '\r' && line[linelen] != '\r') - { - if (line + linelen >= p + n) - return; - linelen++; - } - r = getcontentlenfromline (line, linelen); - if (r > 0) - *contentlen = r; - line = line + linelen + 2; - if (line[0] == '\r' && line[1] == '\n') - { - *headerlen = (line - p) + 2; - return; - } - } -} - -/* 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) -{ - struct sockaddr_in dest; - struct sockaddr_in6 dest6; - char hostname[MAXHOSTNAMELEN + 1]; - unsigned short port = 0; - char *path; - char soapact[128]; - char soapbody[2048]; - char *buf; - int buffree; - int n; - int err; - int contentlen, headerlen; /* for the response */ - snprintf (soapact, sizeof (soapact), "%s#%s", service, action); - if (args == NULL) - { - /*soapbodylen = */ snprintf (soapbody, sizeof (soapbody), - "\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX - "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX - ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" "<" SERVICEPREFIX - ":%s xmlns:" SERVICEPREFIX "=\"%s\">" "" "" "\r\n", - action, service, action); - } - else - { - char *p; - const char *pe, *pv; - int soapbodylen; - soapbodylen = snprintf (soapbody, sizeof (soapbody), - "\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX - "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX - ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" "<" SERVICEPREFIX - ":%s xmlns:" SERVICEPREFIX "=\"%s\">", action, - service); - p = soapbody + soapbodylen; - while (args->elt) - { - /* check that we are never overflowing the string... */ - if (soapbody + sizeof (soapbody) <= p + 100) - { - /* we keep a margin of at least 100 bytes */ - *bufsize = 0; - return -1; - } - *(p++) = '<'; - pe = args->elt; - while (*pe) - *(p++) = *(pe++); - *(p++) = '>'; - if ((pv = args->val)) - { - while (*pv) - *(p++) = *(pv++); - } - *(p++) = '<'; - *(p++) = '/'; - pe = args->elt; - while (*pe) - *(p++) = *(pe++); - *(p++) = '>'; - args++; - } - *(p++) = '<'; - *(p++) = '/'; - *(p++) = SERVICEPREFIX2; - *(p++) = ':'; - pe = action; - while (*pe) - *(p++) = *(pe++); - strncpy (p, ">\r\n", - soapbody + sizeof (soapbody) - p); - } - if (!parseURL (url, hostname, &port, &path)) - return -1; - - if (s < 0) - { - /* Test IPv4 address, else use IPv6 */ - if (inet_pton (AF_INET, hostname, &dest.sin_addr) == 1) - { - memset (&dest, 0, sizeof (dest)); - dest.sin_family = AF_INET; - dest.sin_port = htons (port); -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - dest.sin_len = sizeof (dest); -#endif - if ((s = socket (PF_INET, SOCK_STREAM, 0)) < 0) - { - PRINT_SOCKET_ERROR ("socket"); - *bufsize = 0; - return -1; - } - err = connect (s, (struct sockaddr *) &dest, sizeof (dest)); - } - else if (inet_pton (AF_INET6, hostname, &dest6.sin6_addr) == 1) - { - memset (&dest6, 0, sizeof (dest6)); - dest6.sin6_family = AF_INET6; - dest6.sin6_port = htons (port); -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - dest6.sin6_len = sizeof (dest6); -#endif - if ((s = socket (PF_INET6, SOCK_STREAM, 0)) < 0) - { - PRINT_SOCKET_ERROR ("socket"); - *bufsize = 0; - return -1; - } - err = connect (s, (struct sockaddr *) &dest6, sizeof (dest6)); - } - else - { - PRINT_SOCKET_ERROR ("inet_pton"); - if (s > 0) - closesocket (s); - - *bufsize = 0; - return -1; - } - - if (err < 0) - { - PRINT_SOCKET_ERROR ("connect"); - closesocket (s); - *bufsize = 0; - return -1; - } - } - n = soapPostSubmit (s, path, hostname, port, soapact, soapbody); - if (n <= 0) - { -#ifdef DEBUG - printf ("Error sending SOAP request\n"); -#endif - closesocket (s); - return -1; - } - - contentlen = -1; - headerlen = -1; - buf = buffer; - buffree = *bufsize; - *bufsize = 0; - while ((n = ReceiveData (s, buf, buffree, 5000)) > 0) - { - buffree -= n; - buf += n; - *bufsize += n; - getContentLengthAndHeaderLength (buffer, *bufsize, - &contentlen, &headerlen); -#ifdef DEBUG - printf ("received n=%dbytes bufsize=%d ContLen=%d HeadLen=%d\n", - n, *bufsize, contentlen, headerlen); -#endif - /* break if we received everything */ - if (contentlen > 0 && headerlen > 0 - && *bufsize >= contentlen + headerlen) - break; - } - - closesocket (s); - return 0; -} - -/* parseMSEARCHReply() - * the last 4 arguments are filled during the parsing : - * - location/locationsize : "location:" field of the SSDP reply packet - * - st/stsize : "st:" field of the SSDP reply packet. - * The strings are NOT null terminated */ -static void -parseMSEARCHReply (const char *reply, int size, - const char **location, int *locationsize, - const char **st, int *stsize) -{ - int a, b, i; - i = 0; - a = i; /* start of the line */ - b = 0; - while (i < size) - { - switch (reply[i]) - { - case ':': - if (b == 0) - { - b = i; /* end of the "header" */ - /*for(j=a; jsa_family == AF_INET) - domain = PF_INET; - else if (addr && addr->sa_family == AF_INET6) - domain = PF_INET6; - else if (addr) - return NULL; - - /* fallback to direct discovery */ -#ifdef WIN32 - sudp = socket (domain, SOCK_DGRAM, IPPROTO_UDP); -#else - sudp = socket (domain, SOCK_DGRAM, 0); -#endif - if (sudp < 0) - { - PRINT_SOCKET_ERROR ("socket"); - return NULL; - } - - if (domain == PF_INET) - { - /* receive */ - memset (&sockudp_r, 0, sizeof (struct sockaddr_in)); - sockudp_r.sin_family = AF_INET; -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - sockudp_r.sin_len = sizeof (struct sockaddr_in); -#endif - if (sameport) - sockudp_r.sin_port = htons (PORT); - sockudp_r.sin_addr.s_addr = INADDR_ANY; - /* send */ - 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); -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - sockudp_w.sin_len = sizeof (struct sockaddr_in); -#endif - } - else - { - /* receive */ - memcpy (&sockudp6_r, addr, sizeof (struct sockaddr_in6)); - if (sameport) - sockudp6_r.sin6_port = htons (PORT); - else - sockudp6_r.sin6_port = 0; - sockudp6_r.sin6_addr = any_addr; -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - sockudp6_r.sin6_len = sizeof (struct sockaddr_in6); -#endif - /* send */ - memset (&sockudp6_w, 0, sizeof (struct sockaddr_in6)); - sockudp6_w.sin6_family = AF_INET6; - sockudp6_w.sin6_port = htons (PORT); - if (inet_pton (AF_INET6, UPNP_MCAST_ADDR6, &sockudp6_w.sin6_addr) != 1) - { - PRINT_SOCKET_ERROR ("inet_pton"); - return NULL; - } -#ifdef HAVE_SOCKADDR_IN_SIN_LEN - sockudp6_w.sin6_len = sizeof (struct sockaddr_in6); -#endif - } - -#ifdef WIN32 - if (setsockopt - (sudp, SOL_SOCKET, SO_REUSEADDR, (const char *) &opt, sizeof (opt)) < 0) -#else - if (setsockopt (sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) -#endif - { - PRINT_SOCKET_ERROR ("setsockopt"); - return NULL; - } - - if (addr) - { - if (domain == PF_INET) - { - sockudp_r.sin_addr.s_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; - if (setsockopt - (sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *) &sockudp_r.sin_addr, - sizeof (struct in_addr)) < 0) - { - PRINT_SOCKET_ERROR ("setsockopt"); - } - - /* Bind to receive response before sending packet */ - if (bind (sudp, (struct sockaddr *) &sockudp_r, sizeof (struct sockaddr_in)) - != 0) - { - PRINT_SOCKET_ERROR ("bind"); - closesocket (sudp); - return NULL; - } - } - else - { - if (multicastif) - { - if_index = if_nametoindex (multicastif); - if (!if_index) - PRINT_SOCKET_ERROR ("if_nametoindex"); - - if (setsockopt - (sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_index, sizeof (if_index)) < 0) - { - PRINT_SOCKET_ERROR ("setsockopt"); - } - } - - /* Bind to receive response before sending packet */ - memcpy (&sockudp6_r.sin6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr, - sizeof (sockudp6_r.sin6_addr)); - if (bind (sudp, (struct sockaddr *) &sockudp6_r, sizeof (struct sockaddr_in6)) - != 0) - { - PRINT_SOCKET_ERROR ("bind"); - closesocket (sudp); - return NULL; - } - } - } - - /* receiving SSDP response packet */ - for (n = 0;;) - { - if (n == 0) - { - /* sending the SSDP M-SEARCH packet */ - n = snprintf (bufr, sizeof (bufr), - MSearchMsgFmt, deviceList[deviceIndex++]); - /*printf("Sending %s", bufr); */ - if (domain == PF_INET) - n = sendto (sudp, bufr, n, 0, - (struct sockaddr *) &sockudp_w, - sizeof (struct sockaddr_in)); - else - n = sendto (sudp, bufr, n, 0, - (struct sockaddr *) &sockudp6_w, - sizeof (struct sockaddr_in6)); - - if (n < 0) - { - PRINT_SOCKET_ERROR ("sendto"); - closesocket (sudp); - return devlist; - } - } - /* Waiting for SSDP REPLY packet to M-SEARCH */ - n = ReceiveData (sudp, bufr, sizeof (bufr), delay); - - if (n < 0) - { - /* error */ - closesocket (sudp); - return devlist; - } - else if (n == 0) - { - /* no data or Time Out */ - if (devlist || (deviceList[deviceIndex] == 0)) - { - /* no more device type to look for... */ - closesocket (sudp); - return devlist; - } - } - else - { - const char *descURL = NULL; - int urlsize = 0; - const char *st = NULL; - int stsize = 0; - /*printf("%d byte(s) :\n%s\n", n, bufr); *//* affichage du message */ - parseMSEARCHReply (bufr, n, &descURL, &urlsize, &st, &stsize); - if (st && descURL) - { - /*printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n", - stsize, st, urlsize, descURL); */ - tmp = - (struct UPNPDev *) malloc (sizeof (struct UPNPDev) + urlsize + - stsize); - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - memcpy (tmp->buffer, descURL, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy (tmp->buffer + urlsize + 1, st, stsize); - tmp->buffer[urlsize + 1 + stsize] = '\0'; - devlist = tmp; - } - } - } -} - -/* freeUPNPDevlist() should be used to - * free the chained list returned by upnpDiscover() */ -void -freeUPNPDevlist (struct UPNPDev *devlist) -{ - struct UPNPDev *next; - while (devlist) - { - next = devlist->pNext; - free (devlist); - devlist = next; - } -} - -static void -url_cpy_or_cat (char *dst, const char *src, int n) -{ - if ((src[0] == 'h') - && (src[1] == 't') - && (src[2] == 't') - && (src[3] == 'p') - && (src[4] == ':') && (src[5] == '/') && (src[6] == '/')) - { - strncpy (dst, src, n); - } - else - { - int l = strlen (dst); - if (src[0] != '/') - dst[l++] = '/'; - if (l <= n) - strncpy (dst + l, src, n - l); - } -} - -/* Prepare the Urls for usage... - */ -void -GetUPNPUrls (struct UPNPUrls *urls, struct IGDdatas *data, - const char *descURL) -{ - char *p; - int n1, n2, n3; - n1 = strlen (data->urlbase); - if (n1 == 0) - 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); - - urls->ipcondescURL = (char *) malloc (n1); - urls->controlURL = (char *) malloc (n2); - urls->controlURL_CIF = (char *) malloc (n3); - /* maintenant on chope la desc du WANIPConnection */ - if (data->urlbase[0] != '\0') - strncpy (urls->ipcondescURL, data->urlbase, n1); - else - strncpy (urls->ipcondescURL, descURL, n1); - p = strchr (urls->ipcondescURL + 7, '/'); - if (p) - p[0] = '\0'; - 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->controlURL, data->controlurl, n2); - - url_cpy_or_cat (urls->controlURL_CIF, data->controlurl_CIF, 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); -#endif -} - -void -FreeUPNPUrls (struct UPNPUrls *urls) -{ - if (!urls) - return; - free (urls->controlURL); - urls->controlURL = 0; - free (urls->ipcondescURL); - urls->ipcondescURL = 0; - free (urls->controlURL_CIF); - urls->controlURL_CIF = 0; -} - - -int -ReceiveData (int socket, char *data, int length, int timeout) -{ - int n; -#ifndef WIN32 - struct pollfd fds[1]; /* for the poll */ - fds[0].fd = socket; - fds[0].events = POLLIN; - n = poll (fds, 1, timeout); - if (n < 0) - { - PRINT_SOCKET_ERROR ("poll"); - return -1; - } - else if (n == 0) - { - return 0; - } -#else - fd_set socketSet; - TIMEVAL timeval; - FD_ZERO (&socketSet); - 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) - { - PRINT_SOCKET_ERROR ("select"); - return -1; - } - else if (n == 0) - { - return 0; - } -#endif - n = recv (socket, data, length, 0); - if (n < 0) - { - PRINT_SOCKET_ERROR ("recv"); - } - return n; -} - -int -UPNPIGD_IsConnected (struct UPNPUrls *urls, struct IGDdatas *data) -{ - char status[64]; - unsigned int uptime; - status[0] = '\0'; - UPNP_GetStatusInfo (urls->controlURL, data->servicetype, - status, &uptime, NULL); - if (0 == strcmp ("Connected", status)) - { - return 1; - } - else - return 0; -} - - -/* UPNP_GetValidIGD() : - * return values : - * 0 = NO IGD found - * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as - * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD - * - * In any non zero return case, the urls and data structures - * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ -int -UPNP_GetValidIGD (struct UPNPDev *devlist, - struct UPNPUrls *urls, - struct IGDdatas *data, char *lanaddr, int lanaddrlen) -{ - char *descXML; - int descXMLsize = 0; - struct UPNPDev *dev; - int ndev = 0; - int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ - if (!devlist) - { -#ifdef DEBUG - printf ("Empty devlist\n"); -#endif - return 0; - } - for (state = 1; state <= 3; state++) - { - for (dev = devlist; dev; dev = dev->pNext) - { - /* we should choose an internet gateway device. - * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ - descXML = miniwget_getaddr (dev->descURL, &descXMLsize, - lanaddr, lanaddrlen); - if (descXML) - { - ndev++; - memset (data, 0, sizeof (struct IGDdatas)); - memset (urls, 0, sizeof (struct UPNPUrls)); - parserootdesc (descXML, descXMLsize, data); - free (descXML); - descXML = NULL; - if (0 == strcmp (data->servicetype_CIF, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1") - || state >= 3) - { - 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)); - } -#ifdef DEBUG - else - { - printf ("error getting XML description %s\n", dev->descURL); - } -#endif - } - } - return 0; -} - -/* UPNP_GetIGDFromUrl() - * Used when skipping the discovery process. - * return value : - * 0 - Not ok - * 1 - OK */ -int -UPNP_GetIGDFromUrl (const char *rootdescurl, - struct UPNPUrls *urls, - struct IGDdatas *data, char *lanaddr, int lanaddrlen) -{ - char *descXML; - int descXMLsize = 0; - descXML = miniwget_getaddr (rootdescurl, &descXMLsize, lanaddr, lanaddrlen); - if (descXML) - { - memset (data, 0, sizeof (struct IGDdatas)); - memset (urls, 0, sizeof (struct UPNPUrls)); - parserootdesc (descXML, descXMLsize, data); - free (descXML); - descXML = NULL; - GetUPNPUrls (urls, data, rootdescurl); - return 1; - } - else - { - return 0; - } -} diff --git a/src/nat/miniupnp/miniupnpc.h b/src/nat/miniupnp/miniupnpc.h deleted file mode 100644 index 8aa047b64..000000000 --- a/src/nat/miniupnp/miniupnpc.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $Id: miniupnpc.h,v 1.18 2008/09/25 18:02:50 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ - * Author: Thomas Bernard - * Copyright (c) 2005-2006 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef __MINIUPNPC_H__ -#define __MINIUPNPC_H__ - -#include "declspec.h" -#include "igd_desc_parse.h" - -#ifdef WIN32 -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Structures definitions : */ - struct UPNParg - { - const char *elt; - const char *val; - }; - - int simpleUPnPcommand (int s, const char *, const char *, - const char *, struct UPNParg *, char *, int *); - - struct UPNPDev - { - struct UPNPDev *pNext; - char *descURL; - char *st; - char buffer[2]; - }; - -/* upnpDiscover() - * discover UPnP devices on the network. - * The discovered devices are returned as a chained list. - * It is up to the caller to free the list with freeUPNPDevlist(). - * delay (in millisecond) is the maximum time for waiting any device - * response. - * If available, device list will be obtained from MiniSSDPd. - * Default path for minissdpd socket will be used if minissdpdsock argument - * is NULL. - * If multicastif is not NULL, it will be used instead of the default - * multicast interface for sending SSDP discover packets. - * If sameport is not null, SSDP packets will be sent from the source port - * 1900 (same as destination port) otherwise system assign a source port. */ - LIBSPEC struct UPNPDev *upnpDiscover (int delay, const char *multicastif, const struct sockaddr *addr, - const char *minissdpdsock, int sameport); -/* freeUPNPDevlist() - * free list returned by upnpDiscover() */ - LIBSPEC void freeUPNPDevlist (struct UPNPDev *devlist); - -/* parserootdesc() : - * parse root XML description of a UPnP device and fill the IGDdatas - * structure. */ - LIBSPEC void parserootdesc (const char *, int, struct IGDdatas *); - -/* structure used to get fast access to urls - * controlURL: controlURL of the WANIPConnection - * ipcondescURL: url of the description of the WANIPConnection - * controlURL_CIF: controlURL of the WANCommonInterfaceConfig - */ - struct UPNPUrls - { - char *controlURL; - char *ipcondescURL; - char *controlURL_CIF; - }; - -/* UPNP_GetValidIGD() : - * return values : - * 0 = NO IGD found - * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as - * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD - * - * In any non zero return case, the urls and data structures - * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ - LIBSPEC int - UPNP_GetValidIGD (struct UPNPDev *devlist, - struct UPNPUrls *urls, - struct IGDdatas *data, char *lanaddr, int lanaddrlen); - -/* UPNP_GetIGDFromUrl() - * Used when skipping the discovery process. - * return value : - * 0 - Not ok - * 1 - OK */ - LIBSPEC int - UPNP_GetIGDFromUrl (const char *rootdescurl, - struct UPNPUrls *urls, - struct IGDdatas *data, char *lanaddr, int lanaddrlen); - - LIBSPEC void GetUPNPUrls (struct UPNPUrls *, struct IGDdatas *, - const char *); - - LIBSPEC void FreeUPNPUrls (struct UPNPUrls *); - -/* Reads data from the specified socket. - * Returns the number of bytes read if successful, zero if no bytes were - * read or if we timed out. Returns negative if there was an error. */ - int ReceiveData (int socket, char *data, int length, int timeout); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/nat/miniupnp/miniupnpcstrings.h b/src/nat/miniupnp/miniupnpcstrings.h deleted file mode 100644 index 3245e1f69..000000000 --- a/src/nat/miniupnp/miniupnpcstrings.h +++ /dev/null @@ -1,14 +0,0 @@ -/* $Id: miniupnpcstrings.h,v 1.2 2008/10/14 17:39:04 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2008 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 "Debian/4.0" -#define MINIUPNPC_VERSION_STRING "1.2" - -#endif diff --git a/src/nat/miniupnp/miniwget.c b/src/nat/miniupnp/miniwget.c deleted file mode 100644 index 38d5610d8..000000000 --- a/src/nat/miniupnp/miniwget.c +++ /dev/null @@ -1,224 +0,0 @@ -/* $Id: miniwget.c,v 1.22 2009/02/28 10:36:35 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#include -#include -#include -#include "miniupnpc.h" -#ifdef WIN32 -#include -#include -#define MAXHOSTNAMELEN 64 -#define MIN(x,y) (((x)<(y))?(x):(y)) -#define snprintf _snprintf -#define herror -#define socklen_t int -#else -#include -#include -#include -#include -#include -#include -#define closesocket close -#endif -#if defined(__sun) || defined(sun) -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif - -#include "miniupnpcstrings.h" - -/* miniwget2() : - * */ -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 buf[2048]; - int s; - struct sockaddr_in dest; - struct hostent *hp; - *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); - 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; - - len = sizeof (saddr); - getsockname (s, (struct sockaddr *) &saddr, &len); -#ifndef WIN32 - inet_ntop (AF_INET, &saddr.sin_addr, addr_str, addr_str_len); -#else - /* 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), - NULL, addr_str, (DWORD *)&addr_str_len)) - { - printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); - }*/ - strncpy (addr_str, inet_ntoa (saddr.sin_addr), addr_str_len); -#endif -#ifdef DEBUG - printf ("address miniwget : %s\n", addr_str); -#endif - } - - snprintf (buf, sizeof (buf), - "GET %s HTTP/1.1\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); - { - int n, headers = 1; - char *respbuffer = NULL; - int allreadyread = 0; - /*while((n = recv(s, buf, 2048, 0)) > 0) */ - while ((n = ReceiveData (s, buf, 2048, 5000)) > 0) - { - if (headers) - { - int i = 0; - while (i < n - 3) - { - if (buf[i] == '\r' && buf[i + 1] == '\n' - && buf[i + 2] == '\r' && buf[i + 3] == '\n') - { - headers = 0; /* end */ - if (i < n - 4) - { - respbuffer = (char *) realloc ((void *) respbuffer, - allreadyread + (n - i - - 4)); - memcpy (respbuffer + allreadyread, buf + i + 4, - n - i - 4); - allreadyread += (n - i - 4); - } - break; - } - i++; - } - } - else - { - respbuffer = (char *) realloc ((void *) respbuffer, - allreadyread + n); - memcpy (respbuffer + allreadyread, buf, n); - allreadyread += n; - } - } - *size = allreadyread; -#ifdef DEBUG - printf ("%d bytes read\n", *size); -#endif - closesocket (s); - return respbuffer; - } -} - -/* parseURL() - * arguments : - * url : source string not modified - * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) - * port : port (destination) - * path : pointer to the path part of the URL - * - * Return values : - * 0 - Failure - * 1 - Success */ -int -parseURL (const char *url, char *hostname, unsigned short *port, char **path) -{ - char *p1, *p2, *p3; - p1 = strstr (url, "://"); - if (!p1) - return 0; - p1 += 3; - if ((url[0] != 'h') || (url[1] != 't') - || (url[2] != 't') || (url[3] != 'p')) - return 0; - p2 = strchr (p1, ':'); - p3 = strchr (p1, '/'); - if (!p3) - return 0; - memset (hostname, 0, MAXHOSTNAMELEN + 1); - if (!p2 || (p2 > p3)) - { - strncpy (hostname, p1, MIN (MAXHOSTNAMELEN, (int) (p3 - p1))); - *port = 80; - } - else - { - strncpy (hostname, p1, MIN (MAXHOSTNAMELEN, (int) (p2 - p1))); - *port = 0; - p2++; - while ((*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short) (*p2 - '0'); - p2++; - } - } - *path = p3; - return 1; -} - -void * -miniwget (const char *url, int *size) -{ - unsigned short port; - char *path; - /* protocol://host:port/chemin */ - char hostname[MAXHOSTNAMELEN + 1]; - *size = 0; - if (!parseURL (url, hostname, &port, &path)) - return NULL; - return miniwget2 (url, hostname, port, path, size, 0, 0); -} - -void * -miniwget_getaddr (const char *url, int *size, char *addr, int addrlen) -{ - unsigned short port; - char *path; - /* protocol://host:port/chemin */ - char hostname[MAXHOSTNAMELEN + 1]; - *size = 0; - if (addr) - addr[0] = '\0'; - if (!parseURL (url, hostname, &port, &path)) - return NULL; - return miniwget2 (url, hostname, port, path, size, addr, addrlen); -} diff --git a/src/nat/miniupnp/miniwget.h b/src/nat/miniupnp/miniwget.h deleted file mode 100644 index 04e91df64..000000000 --- a/src/nat/miniupnp/miniwget.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $Id: miniwget.h,v 1.5 2007/01/29 20:27:23 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef __MINIWGET_H__ -#define __MINIWGET_H__ - -#include "declspec.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - - LIBSPEC void *miniwget (const char *, int *); - - LIBSPEC void *miniwget_getaddr (const char *, int *, char *, int); - - int parseURL (const char *, char *, unsigned short *, char **); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/nat/miniupnp/minixml.c b/src/nat/miniupnp/minixml.c deleted file mode 100644 index 094118cfa..000000000 --- a/src/nat/miniupnp/minixml.c +++ /dev/null @@ -1,200 +0,0 @@ -/* $Id: minixml.c,v 1.6 2007/05/15 18:14:08 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 -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 "minixml.h" - -/* 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) -{ - const char *attname; - int attnamelen; - const char *attvalue; - int attvaluelen; - while (p->xml < p->xmlend) - { - if (*p->xml == '/' || *p->xml == '>') - return 0; - if (!IS_WHITE_SPACE (*p->xml)) - { - char sep; - attname = p->xml; - attnamelen = 0; - while (*p->xml != '=' && !IS_WHITE_SPACE (*p->xml)) - { - attnamelen++; - p->xml++; - if (p->xml >= p->xmlend) - return -1; - } - while (*(p->xml++) != '=') - { - if (p->xml >= p->xmlend) - return -1; - } - while (IS_WHITE_SPACE (*p->xml)) - { - p->xml++; - if (p->xml >= p->xmlend) - return -1; - } - sep = *p->xml; - if (sep == '\'' || sep == '\"') - { - p->xml++; - if (p->xml >= p->xmlend) - return -1; - attvalue = p->xml; - attvaluelen = 0; - while (*p->xml != sep) - { - attvaluelen++; - p->xml++; - if (p->xml >= p->xmlend) - return -1; - } - } - else - { - attvalue = p->xml; - attvaluelen = 0; - while (!IS_WHITE_SPACE (*p->xml) - && *p->xml != '>' && *p->xml != '/') - { - attvaluelen++; - p->xml++; - if (p->xml >= p->xmlend) - return -1; - } - } - /*printf("%.*s='%.*s'\n", - attnamelen, attname, attvaluelen, attvalue); */ - if (p->attfunc) - p->attfunc (p->data, attname, attnamelen, attvalue, attvaluelen); - } - p->xml++; - } - return -1; -} - -/* parseelt parse the xml stream and - * call the callback functions when needed... */ -void -parseelt (struct xmlparser *p) -{ - int i; - const char *elementname; - while (p->xml < (p->xmlend - 1)) - { - if ((p->xml)[0] == '<' && (p->xml)[1] != '?') - { - i = 0; - elementname = ++p->xml; - while (!IS_WHITE_SPACE (*p->xml) - && (*p->xml != '>') && (*p->xml != '/')) - { - i++; - p->xml++; - if (p->xml >= p->xmlend) - return; - /* to ignore namespace : */ - if (*p->xml == ':') - { - i = 0; - elementname = ++p->xml; - } - } - if (i > 0) - { - if (p->starteltfunc) - p->starteltfunc (p->data, elementname, i); - if (parseatt (p)) - return; - if (*p->xml != '/') - { - const char *data; - i = 0; - data = ++p->xml; - if (p->xml >= p->xmlend) - return; - while (IS_WHITE_SPACE (*p->xml)) - { - p->xml++; - if (p->xml >= p->xmlend) - return; - } - while (*p->xml != '<') - { - i++; - p->xml++; - if (p->xml >= p->xmlend) - return; - } - if (i > 0 && p->datafunc) - p->datafunc (p->data, data, i); - } - } - else if (*p->xml == '/') - { - i = 0; - elementname = ++p->xml; - if (p->xml >= p->xmlend) - return; - while ((*p->xml != '>')) - { - i++; - p->xml++; - if (p->xml >= p->xmlend) - return; - } - if (p->endeltfunc) - p->endeltfunc (p->data, elementname, i); - p->xml++; - } - } - else - { - p->xml++; - } - } -} - -/* the parser must be initialized before calling this function */ -void -parsexml (struct xmlparser *parser) -{ - parser->xml = parser->xmlstart; - parser->xmlend = parser->xmlstart + parser->xmlsize; - parseelt (parser); -} diff --git a/src/nat/miniupnp/minixml.h b/src/nat/miniupnp/minixml.h deleted file mode 100644 index 6ffb987ac..000000000 --- a/src/nat/miniupnp/minixml.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id: minixml.h,v 1.6 2006/11/30 11:47:21 nanard Exp $ */ -/* minimal xml parser - * - * Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef __MINIXML_H__ -#define __MINIXML_H__ -#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) - -/* if a callback function pointer is set to NULL, - * the function is not called */ -struct xmlparser -{ - const char *xmlstart; - const char *xmlend; - const char *xml; /* pointer to current character */ - int xmlsize; - void *data; - void (*starteltfunc) (void *, const char *, int); - void (*endeltfunc) (void *, const char *, int); - void (*datafunc) (void *, const char *, int); - void (*attfunc) (void *, const char *, int, const char *, int); -}; - -/* parsexml() - * the xmlparser structure must be initialized before the call - * the following structure members have to be initialized : - * xmlstart, xmlsize, data, *func - * xml is for internal usage, xmlend is computed automatically */ -void parsexml (struct xmlparser *); - -#endif diff --git a/src/nat/miniupnp/upnpcommands.c b/src/nat/miniupnp/upnpcommands.c deleted file mode 100644 index 8b59bc7cc..000000000 --- a/src/nat/miniupnp/upnpcommands.c +++ /dev/null @@ -1,605 +0,0 @@ -/* $Id: upnpcommands.c,v 1.24 2009/04/17 21:21:19 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 -#include -#include -#include "upnpcommands.h" -#include "miniupnpc.h" - -static UNSIGNED_INTEGER -my_atoui (const char *s) -{ - return s ? ((UNSIGNED_INTEGER) STRTOUI (s, NULL, 0)) : 0; -} - -/* - * */ -UNSIGNED_INTEGER -UPNP_GetTotalBytesSent (const char *controlURL, const char *servicetype) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - unsigned int r = 0; - char *p; - simpleUPnPcommand (-1, controlURL, servicetype, "GetTotalBytesSent", 0, - buffer, &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize); */ - p = GetValueFromNameValueList (&pdata, "NewTotalBytesSent"); - r = my_atoui (p); - ClearNameValueList (&pdata); - return r; -} - -/* - * */ -UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived (const char *controlURL, const char *servicetype) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - unsigned int r = 0; - char *p; - simpleUPnPcommand (-1, controlURL, servicetype, "GetTotalBytesReceived", 0, - buffer, &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize); */ - p = GetValueFromNameValueList (&pdata, "NewTotalBytesReceived"); - r = my_atoui (p); - ClearNameValueList (&pdata); - return r; -} - -/* - * */ -UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent (const char *controlURL, const char *servicetype) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - unsigned int r = 0; - char *p; - simpleUPnPcommand (-1, controlURL, servicetype, "GetTotalPacketsSent", 0, - buffer, &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize); */ - p = GetValueFromNameValueList (&pdata, "NewTotalPacketsSent"); - r = my_atoui (p); - ClearNameValueList (&pdata); - return r; -} - -/* - * */ -UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived (const char *controlURL, const char *servicetype) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - unsigned int r = 0; - char *p; - simpleUPnPcommand (-1, controlURL, servicetype, "GetTotalPacketsReceived", - 0, buffer, &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize); */ - p = GetValueFromNameValueList (&pdata, "NewTotalPacketsReceived"); - r = my_atoui (p); - ClearNameValueList (&pdata); - return r; -} - -/* 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) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - char *p; - char *up; - char *err; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if (!status && !uptime) - return UPNPCOMMAND_INVALID_ARGS; - - simpleUPnPcommand (-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, - &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize); */ - up = GetValueFromNameValueList (&pdata, "NewUptime"); - p = GetValueFromNameValueList (&pdata, "NewConnectionStatus"); - err = GetValueFromNameValueList (&pdata, "NewLastConnectionError"); - if (p && up) - ret = UPNPCOMMAND_SUCCESS; - - if (status) - { - if (p) - { - strncpy (status, p, 64); - status[63] = '\0'; - } - else - status[0] = '\0'; - } - - if (uptime) - { - if (up) - sscanf (up, "%u", uptime); - else - uptime = 0; - } - - if (lastconnerror) - { - if (err) - { - strncpy (lastconnerror, err, 64); - lastconnerror[63] = '\0'; - } - else - lastconnerror[0] = '\0'; - } - - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &ret); - } - ClearNameValueList (&pdata); - return ret; -} - -/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method - * returns the connection type */ -int -UPNP_GetConnectionTypeInfo (const char *controlURL, - const char *servicetype, char *connectionType) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - char *p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if (!connectionType) - return UPNPCOMMAND_INVALID_ARGS; - - simpleUPnPcommand (-1, controlURL, servicetype, - "GetConnectionTypeInfo", 0, buffer, &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - p = GetValueFromNameValueList (&pdata, "NewConnectionType"); - /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes"); */ - /* PossibleConnectionTypes will have several values.... */ - if (p) - { - strncpy (connectionType, p, 64); - connectionType[63] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } - else - connectionType[0] = '\0'; - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &ret); - } - ClearNameValueList (&pdata); - return ret; -} - -/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. - * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. - * 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) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - char *down; - char *up; - char *p; - - if (!bitrateDown && !bitrateUp) - return UPNPCOMMAND_INVALID_ARGS; - - /* shouldn't we use GetCommonLinkProperties ? */ - simpleUPnPcommand (-1, controlURL, servicetype, - "GetCommonLinkProperties", 0, buffer, &bufsize); - /*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize); */ - /*DisplayNameValueList(buffer, bufsize); */ - ParseNameValue (buffer, bufsize, &pdata); - /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate"); */ - /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate"); */ - down = GetValueFromNameValueList (&pdata, "NewLayer1DownstreamMaxBitRate"); - up = GetValueFromNameValueList (&pdata, "NewLayer1UpstreamMaxBitRate"); - /*GetValueFromNameValueList(&pdata, "NewWANAccessType"); */ - /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus"); */ - if (down && up) - ret = UPNPCOMMAND_SUCCESS; - - if (bitrateDown) - { - if (down) - sscanf (down, "%u", bitrateDown); - else - *bitrateDown = 0; - } - - if (bitrateUp) - { - if (up) - sscanf (up, "%u", bitrateUp); - else - *bitrateUp = 0; - } - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &ret); - } - ClearNameValueList (&pdata); - return ret; -} - - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 128 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * 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) -{ - struct NameValueParserData pdata; - char buffer[4096]; - int bufsize = 4096; - char *p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if (!extIpAdd || !controlURL || !servicetype) - return UPNPCOMMAND_INVALID_ARGS; - - simpleUPnPcommand (-1, controlURL, servicetype, "GetExternalIPAddress", 0, - buffer, &bufsize); - /*DisplayNameValueList(buffer, bufsize); */ - ParseNameValue (buffer, bufsize, &pdata); - /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") ); */ - p = GetValueFromNameValueList (&pdata, "NewExternalIPAddress"); - if (p) - { - strncpy (extIpAdd, p, 128); - extIpAdd[127] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } - else - extIpAdd[0] = '\0'; - - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &ret); - } - - ClearNameValueList (&pdata); - return ret; -} - -int -UPNP_AddPortMapping (const char *controlURL, const char *servicetype, - const char *extPort, - const char *inPort, - const char *inClient, - const char *desc, - const char *proto, const char *remoteHost) -{ - struct UPNParg *AddPortMappingArgs; - char buffer[4096]; - int bufsize = 4096; - struct NameValueParserData pdata; - const char *resVal; - int ret; - - if (!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc (9, sizeof (struct UPNParg)); - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc ? desc : "libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = "0"; - simpleUPnPcommand (-1, controlURL, servicetype, "AddPortMapping", - AddPortMappingArgs, buffer, &bufsize); - /*DisplayNameValueList(buffer, bufsize); */ - /*buffer[bufsize] = '\0'; */ - /*puts(buffer); */ - ParseNameValue (buffer, bufsize, &pdata); - resVal = GetValueFromNameValueList (&pdata, "errorCode"); - if (resVal) - { - /* printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList (&pdata); - free (AddPortMappingArgs); - return ret; -} - -int -UPNP_DeletePortMapping (const char *controlURL, const char *servicetype, - const char *extPort, const char *proto, - const char *remoteHost) -{ - /*struct NameValueParserData pdata; */ - struct UPNParg *DeletePortMappingArgs; - char buffer[4096]; - int bufsize = 4096; - struct NameValueParserData pdata; - const char *resVal; - int ret; - - if (!extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc (4, sizeof (struct UPNParg)); - DeletePortMappingArgs[0].elt = "NewRemoteHost"; - DeletePortMappingArgs[0].val = remoteHost; - DeletePortMappingArgs[1].elt = "NewExternalPort"; - DeletePortMappingArgs[1].val = extPort; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - simpleUPnPcommand (-1, controlURL, servicetype, - "DeletePortMapping", - DeletePortMappingArgs, buffer, &bufsize); - /*DisplayNameValueList(buffer, bufsize); */ - ParseNameValue (buffer, bufsize, &pdata); - resVal = GetValueFromNameValueList (&pdata, "errorCode"); - if (resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList (&pdata); - free (DeletePortMappingArgs); - 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) -{ - struct NameValueParserData pdata; - struct UPNParg *GetPortMappingArgs; - char buffer[4096]; - int bufsize = 4096; - char *p; - int r = UPNPCOMMAND_UNKNOWN_ERROR; - if (!index) - return UPNPCOMMAND_INVALID_ARGS; - - GetPortMappingArgs = calloc (2, sizeof (struct UPNParg)); - GetPortMappingArgs[0].elt = "NewPortMappingIndex"; - GetPortMappingArgs[0].val = index; - simpleUPnPcommand (-1, controlURL, servicetype, - "GetGenericPortMappingEntry", - GetPortMappingArgs, buffer, &bufsize); - ParseNameValue (buffer, bufsize, &pdata); - p = GetValueFromNameValueList (&pdata, "NewRemoteHost"); - if (p && rHost) - { - strncpy (rHost, p, 64); - rHost[63] = '\0'; - } - p = GetValueFromNameValueList (&pdata, "NewExternalPort"); - if (p && extPort) - { - strncpy (extPort, p, 6); - extPort[5] = '\0'; - r = UPNPCOMMAND_SUCCESS; - } - p = GetValueFromNameValueList (&pdata, "NewProtocol"); - if (p && protocol) - { - strncpy (protocol, p, 4); - protocol[3] = '\0'; - } - p = GetValueFromNameValueList (&pdata, "NewInternalClient"); - if (p && intClient) - { - strncpy (intClient, p, 128); - intClient[127] = '\0'; - r = 0; - } - p = GetValueFromNameValueList (&pdata, "NewInternalPort"); - if (p && intPort) - { - strncpy (intPort, p, 6); - intPort[5] = '\0'; - } - p = GetValueFromNameValueList (&pdata, "NewEnabled"); - if (p && enabled) - { - strncpy (enabled, p, 4); - enabled[3] = '\0'; - } - p = GetValueFromNameValueList (&pdata, "NewPortMappingDescription"); - if (p && desc) - { - strncpy (desc, p, 80); - desc[79] = '\0'; - } - p = GetValueFromNameValueList (&pdata, "NewLeaseDuration"); - if (p && duration) - { - strncpy (duration, p, 16); - duration[15] = '\0'; - } - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - r = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &r); - } - ClearNameValueList (&pdata); - free (GetPortMappingArgs); - return r; -} - -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); -#ifdef DEBUG - DisplayNameValueList (buffer, bufsize); -#endif - ParseNameValue (buffer, bufsize, &pdata); - - p = GetValueFromNameValueList (&pdata, "NewPortMappingNumberOfEntries"); - if (numEntries && p) - { - *numEntries = 0; - sscanf (p, "%u", numEntries); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &ret); - } - - ClearNameValueList (&pdata); - return ret; -} - -/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping - * the result is returned in the intClient and intPort strings - * please provide 128 and 6 bytes of data */ -int -UPNP_GetSpecificPortMappingEntry (const char *controlURL, - const char *servicetype, - const char *extPort, - const char *proto, - char *intClient, char *intPort) -{ - struct NameValueParserData pdata; - struct UPNParg *GetPortMappingArgs; - char buffer[4096]; - int bufsize = 4096; - char *p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if (!intPort || !intClient || !extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - GetPortMappingArgs = calloc (4, sizeof (struct UPNParg)); - GetPortMappingArgs[0].elt = "NewRemoteHost"; - GetPortMappingArgs[1].elt = "NewExternalPort"; - 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); */ - /*DisplayNameValueList(buffer, bufsize); */ - ParseNameValue (buffer, bufsize, &pdata); - - p = GetValueFromNameValueList (&pdata, "NewInternalClient"); - if (p) - { - strncpy (intClient, p, 128); - intClient[127] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } - else - intClient[0] = '\0'; - - p = GetValueFromNameValueList (&pdata, "NewInternalPort"); - if (p) - { - strncpy (intPort, p, 6); - intPort[5] = '\0'; - } - else - intPort[0] = '\0'; - - p = GetValueFromNameValueList (&pdata, "errorCode"); - if (p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf (p, "%d", &ret); - } - - ClearNameValueList (&pdata); - free (GetPortMappingArgs); - return ret; -} diff --git a/src/nat/miniupnp/upnpcommands.h b/src/nat/miniupnp/upnpcommands.h deleted file mode 100644 index fa1d604ae..000000000 --- a/src/nat/miniupnp/upnpcommands.h +++ /dev/null @@ -1,189 +0,0 @@ -/* $Id: upnpcommands.h,v 1.17 2009/04/17 21:21:19 nanard Exp $ */ -/* Miniupnp project : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided within this distribution */ -#ifndef __UPNPCOMMANDS_H__ -#define __UPNPCOMMANDS_H__ - -#include "upnpreplyparse.h" -#include "declspec.h" - -/* MiniUPnPc return codes : */ -#define UPNPCOMMAND_SUCCESS (0) -#define UPNPCOMMAND_UNKNOWN_ERROR (-1) -#define UPNPCOMMAND_INVALID_ARGS (-2) - -#ifdef __cplusplus -extern "C" -{ -#endif - -#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) -#define UNSIGNED_INTEGER unsigned long long -#define STRTOUI strtoull -#else -#define UNSIGNED_INTEGER unsigned int -#define STRTOUI strtoul -#endif - - LIBSPEC UNSIGNED_INTEGER - UPNP_GetTotalBytesSent (const char *controlURL, const char *servicetype); - - LIBSPEC UNSIGNED_INTEGER - UPNP_GetTotalBytesReceived (const char *controlURL, - const char *servicetype); - - LIBSPEC UNSIGNED_INTEGER - UPNP_GetTotalPacketsSent (const char *controlURL, - const char *servicetype); - - LIBSPEC UNSIGNED_INTEGER - UPNP_GetTotalPacketsReceived (const char *controlURL, - const char *servicetype); - -/* UPNP_GetStatusInfo() - * status and lastconnerror are 64 byte buffers - * Return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ - LIBSPEC int - UPNP_GetStatusInfo (const char *controlURL, - const char *servicetype, - char *status, - unsigned int *uptime, char *lastconnerror); - -/* UPNP_GetConnectionTypeInfo() - * argument connectionType is a 64 character buffer - * Return Values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ - LIBSPEC int - UPNP_GetConnectionTypeInfo (const char *controlURL, - const char *servicetype, - char *connectionType); - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 128 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * possible UPnP Errors : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. */ - LIBSPEC int - UPNP_GetExternalIPAddress (const char *controlURL, - const char *servicetype, char *extIpAdd); - -/* UPNP_GetLinkLayerMaxBitRates() - * call WANCommonInterfaceConfig:1#GetCommonLinkProperties - * - * return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. */ - LIBSPEC int - UPNP_GetLinkLayerMaxBitRates (const char *controlURL, - const char *servicetype, - unsigned int *bitrateDown, - unsigned int *bitrateUp); - -/* UPNP_AddPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 718 ConflictInMappingEntry - The port mapping entry specified conflicts - * with a mapping assigned previously to another client - * 724 SamePortValuesRequired - Internal and External port values - * must be the same - * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports - * permanent lease times on port mappings - * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard - * and cannot be a specific IP address or DNS name - * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and - * cannot be a specific port value */ - LIBSPEC int - UPNP_AddPortMapping (const char *controlURL, const char *servicetype, - const char *extPort, - const char *inPort, - const char *inClient, - const char *desc, - const char *proto, const char *remoteHost); - -/* UPNP_DeletePortMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 714 NoSuchEntryInArray - The specified value does not exist in the array */ - LIBSPEC int - UPNP_DeletePortMapping (const char *controlURL, const char *servicetype, - const char *extPort, const char *proto, - const char *remoteHost); - -/* UPNP_GetPortMappingNumberOfEntries() - * not supported by all routers */ - LIBSPEC int - UPNP_GetPortMappingNumberOfEntries (const char *controlURL, - const char *servicetype, - unsigned int *num); - -/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping - * the result is returned in the intClient and intPort strings - * please provide 128 and 6 bytes of data - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. */ - LIBSPEC int - UPNP_GetSpecificPortMappingEntry (const char *controlURL, - const char *servicetype, - const char *extPort, - const char *proto, - char *intClient, char *intPort); - -/* UPNP_GetGenericPortMappingEntry() - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * Possible UPNP Error codes : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds - */ - 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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/nat/miniupnp/upnpreplyparse.c b/src/nat/miniupnp/upnpreplyparse.c deleted file mode 100644 index 9aa895d1d..000000000 --- a/src/nat/miniupnp/upnpreplyparse.c +++ /dev/null @@ -1,122 +0,0 @@ -/* $Id: upnpreplyparse.c,v 1.10 2008/02/21 13:05:27 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#include -#include -#include - -#include "upnpreplyparse.h" -#include "minixml.h" - -static void -NameValueParserStartElt (void *d, const char *name, int l) -{ - struct NameValueParserData *data = (struct NameValueParserData *) d; - if (l > 63) - l = 63; - memcpy (data->curelt, name, l); - data->curelt[l] = '\0'; -} - -static void -NameValueParserGetData (void *d, const char *datas, int l) -{ - struct NameValueParserData *data = (struct NameValueParserData *) d; - struct NameValue *nv; - nv = malloc (sizeof (struct NameValue)); - if (l > 63) - l = 63; - strncpy (nv->name, data->curelt, 64); - nv->name[63] = '\0'; - memcpy (nv->value, datas, l); - nv->value[l] = '\0'; - LIST_INSERT_HEAD (&(data->head), nv, entries); -} - -void -ParseNameValue (const char *buffer, int bufsize, - struct NameValueParserData *data) -{ - struct xmlparser parser; - LIST_INIT (&(data->head)); - /* init xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = NameValueParserStartElt; - parser.endeltfunc = 0; - parser.datafunc = NameValueParserGetData; - parser.attfunc = 0; - parsexml (&parser); -} - -void -ClearNameValueList (struct NameValueParserData *pdata) -{ - struct NameValue *nv; - while ((nv = pdata->head.lh_first) != NULL) - { - LIST_REMOVE (nv, entries); - free (nv); - } -} - -char * -GetValueFromNameValueList (struct NameValueParserData *pdata, - const char *Name) -{ - struct NameValue *nv; - char *p = NULL; - for (nv = pdata->head.lh_first; - (nv != NULL) && (p == NULL); nv = nv->entries.le_next) - { - if (strcmp (nv->name, Name) == 0) - p = nv->value; - } - return p; -} - -#if 0 -/* useless now that minixml ignores namespaces by itself */ -char * -GetValueFromNameValueListIgnoreNS (struct NameValueParserData *pdata, - const char *Name) -{ - struct NameValue *nv; - char *p = NULL; - char *pname; - for (nv = pdata->head.lh_first; - (nv != NULL) && (p == NULL); nv = nv->entries.le_next) - { - pname = strrchr (nv->name, ':'); - if (pname) - pname++; - else - pname = nv->name; - if (strcmp (pname, Name) == 0) - p = nv->value; - } - return p; -} -#endif - -/* debug all-in-one function - * do parsing then display to stdout */ -#ifdef DEBUG -void -DisplayNameValueList (char *buffer, int bufsize) -{ - struct NameValueParserData pdata; - struct NameValue *nv; - ParseNameValue (buffer, bufsize, &pdata); - for (nv = pdata.head.lh_first; nv != NULL; nv = nv->entries.le_next) - { - printf ("%s = %s\n", nv->name, nv->value); - } - ClearNameValueList (&pdata); -} -#endif diff --git a/src/nat/miniupnp/upnpreplyparse.h b/src/nat/miniupnp/upnpreplyparse.h deleted file mode 100644 index a1c8a9431..000000000 --- a/src/nat/miniupnp/upnpreplyparse.h +++ /dev/null @@ -1,60 +0,0 @@ -/* $Id: upnpreplyparse.h,v 1.8 2008/02/21 13:05:27 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006 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) -#include "bsdqueue.h" -#else -#include -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - - struct NameValue - { - LIST_ENTRY (NameValue) entries; - char name[64]; - char value[64]; - }; - - struct NameValueParserData - { - LIST_HEAD (listhead, NameValue) head; - char curelt[64]; - }; - -/* ParseNameValue() */ - void - ParseNameValue (const char *buffer, int bufsize, - struct NameValueParserData *data); - -/* ClearNameValueList() */ - void ClearNameValueList (struct NameValueParserData *pdata); - -/* GetValueFromNameValueList() */ - char *GetValueFromNameValueList (struct NameValueParserData *pdata, - const char *Name); - -/* GetValueFromNameValueListIgnoreNS() */ - char *GetValueFromNameValueListIgnoreNS (struct NameValueParserData *pdata, - const char *Name); - -/* DisplayNameValueList() */ -#ifdef DEBUG - void DisplayNameValueList (char *buffer, int bufsize); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/nat/nat.c b/src/nat/nat.c index 1df0da81a..cb031d35d 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) + (C) 2009, 2010 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -31,152 +31,161 @@ * * @author Milan Bouchet-Valat */ -#include -#include -#include - -#include - #include "platform.h" -#include "gnunet_common.h" #include "gnunet_util_lib.h" #include "gnunet_nat_lib.h" +#include "nat.h" #include "natpmp.h" #include "upnp.h" -/* Component name for logging */ -#define COMP_NAT _("NAT") -#define DEBUG - +/** + * Handle for active NAT registrations. + */ struct GNUNET_NAT_Handle { - int is_enabled; - - enum GNUNET_NAT_port_forwarding natpmp_status; - enum GNUNET_NAT_port_forwarding upnp_status; - - int should_change; - u_short public_port; - + /** + * Handle for UPnP operations. + */ GNUNET_NAT_UPNP_Handle *upnp; + + /** + * Handle for NAT PMP operations. + */ GNUNET_NAT_NATPMP_Handle *natpmp; + /** + * Scheduler. + */ struct GNUNET_SCHEDULER_Handle *sched; - GNUNET_SCHEDULER_TaskIdentifier pulse_timer; - struct sockaddr *local_addr; /* LAN address as passed by the caller */ - struct sockaddr *ext_addr; /* External address as reported by NAT box */ - struct sockaddr *contact_addr; /* External address and port where paquets are redirected*/ + /** + * LAN address as passed by the caller + */ + struct sockaddr *local_addr; + + /** + * External address as reported by NAT box + */ + struct sockaddr *ext_addr; + + /** + * External address and port where packets are redirected + */ + struct sockaddr *contact_addr; + GNUNET_NAT_AddressCallback callback; + + /** + * Closure for 'callback'. + */ void *callback_cls; + + GNUNET_SCHEDULER_TaskIdentifier pulse_timer; + + enum GNUNET_NAT_PortState natpmp_status; + + enum GNUNET_NAT_PortState upnp_status; + + int is_enabled; + + int should_change; + + int port_mapped; + + int did_warn; + + uint16_t public_port; + }; #ifdef DEBUG static const char * -get_nat_state_str (int state) +get_nat_state_str (enum GNUNET_NAT_PortState state) { switch (state) { - /* we're in the process of trying to set up port forwarding */ case GNUNET_NAT_PORT_MAPPING: return "Starting"; - - /* we've successfully forwarded the port */ case GNUNET_NAT_PORT_MAPPED: return "Forwarded"; - - /* we're cancelling the port forwarding */ case GNUNET_NAT_PORT_UNMAPPING: return "Stopping"; - - /* the port isn't forwarded */ case GNUNET_NAT_PORT_UNMAPPED: return "Not forwarded"; - case GNUNET_NAT_PORT_ERROR: return "Redirection failed"; + default: + return "not found"; } - - return "notfound"; } #endif + static int get_traversal_status (const struct GNUNET_NAT_Handle * s) { return MAX (s->natpmp_status, s->upnp_status); } + /** * Compare the sin(6)_addr fields of AF_INET or AF_INET(6) sockaddr. * @param a first sockaddr * @param b second sockaddr * @return 0 if addresses are equal, non-null value otherwise */ int -GNUNET_NAT_cmp_addr (const struct sockaddr *a, const struct sockaddr *b) +GNUNET_NAT_cmp_addr (const struct sockaddr *a, + const struct sockaddr *b) { if (!(a && b)) return -1; - - if (a->sa_family == AF_INET && b->sa_family == AF_INET) + if ( (a->sa_family == AF_INET) && (b->sa_family == AF_INET) ) return memcmp (&(((struct sockaddr_in *) a)->sin_addr), &(((struct sockaddr_in *) b)->sin_addr), sizeof (struct in_addr)); - else if (a->sa_family == AF_INET6 && b->sa_family == AF_INET6) + if ( (a->sa_family == AF_INET6) && (b->sa_family == AF_INET6) ) return memcmp (&(((struct sockaddr_in6 *) a)->sin6_addr), &(((struct sockaddr_in6 *) b)->sin6_addr), sizeof (struct in6_addr)); - else - return -1; + return -1; } -/* Deal with a new IP address or port redirection: + +/** + * Deal with a new IP address or port redirection: * Send signals with the appropriate sockaddr (IP and port), free and changes * or nullify the previous sockaddr. Change the port if needed. */ static void -notify_change (struct GNUNET_NAT_Handle *nat, struct sockaddr *addr, int new_port_mapped) +notify_change (struct GNUNET_NAT_Handle *nat, + struct sockaddr *addr, + size_t addrlen, + int new_port_mapped) { - static int port_mapped = GNUNET_NO; - - /* Nothing to do. We already check in nat_pulse() that addr has changed */ - if (new_port_mapped == port_mapped) + if (new_port_mapped == nat->port_mapped) return; - - port_mapped = new_port_mapped; - - if (nat->contact_addr && nat->callback) - (*nat->callback) (nat->callback_cls, GNUNET_NO, (struct sockaddr *) &nat->contact_addr, - sizeof (nat->contact_addr)); - - /* At this point, we're sure contact_addr has changed */ - if (nat->contact_addr) - { - GNUNET_free (nat->contact_addr); - nat->contact_addr = NULL; - } - - /* No address, don't signal a new one */ - if (!addr) - { - if (nat->ext_addr) - GNUNET_free (nat->ext_addr); - nat->ext_addr = NULL; - return; - } - /* Copy the new address and use it */ - else if (addr != nat->ext_addr) - { - if (nat->ext_addr) - GNUNET_free (nat->ext_addr); - nat->ext_addr = GNUNET_malloc (sizeof (*addr)); - memcpy (nat->ext_addr, addr, sizeof (*addr)); - } + nat->port_mapped = new_port_mapped; + + if ( (NULL != nat->contact_addr) && + (NULL != nat->callback) ) + nat->callback (nat->callback_cls, + GNUNET_NO, + nat->contact_addr, + sizeof (nat->contact_addr)); + GNUNET_free_non_null (nat->contact_addr); + nat->contact_addr = NULL; + GNUNET_free_non_null (nat->ext_addr); + nat->ext_addr = NULL; + if (NULL == addr) + return; + nat->ext_addr = GNUNET_malloc (addrlen); + memcpy (nat->ext_addr, addr, addrlen); /* Recreate the ext_addr:public_port bogus address to pass to the callback */ if (nat->ext_addr->sa_family == AF_INET) { - struct sockaddr_in *tmp_addr; + struct sockaddr_in tmp_addr; + tmp_addr = GNUNET_malloc (sizeof (struct sockaddr_in)); tmp_addr->sin_family = AF_INET; #ifdef HAVE_SOCKADDR_IN_SIN_LEN @@ -185,13 +194,16 @@ notify_change (struct GNUNET_NAT_Handle *nat, struct sockaddr *addr, int new_por tmp_addr->sin_port = port_mapped ? htons (nat->public_port) : 0; tmp_addr->sin_addr = ((struct sockaddr_in *) nat->ext_addr)->sin_addr; nat->contact_addr = (struct sockaddr *) tmp_addr; - if (nat->callback) - (*nat->callback) (nat->callback_cls, GNUNET_YES, nat->contact_addr, - sizeof (struct sockaddr_in)); + if (NULL != nat->callback) + nat->callback (nat->callback_cls, + GNUNET_YES, + nat->contact_addr, + sizeof (struct sockaddr_in)); } else if (nat->ext_addr->sa_family == AF_INET6) { struct sockaddr_in6 *tmp_addr; + tmp_addr = GNUNET_malloc (sizeof (struct sockaddr_in6)); tmp_addr->sin6_family = AF_INET6; #ifdef HAVE_SOCKADDR_IN_SIN_LEN @@ -200,23 +212,31 @@ notify_change (struct GNUNET_NAT_Handle *nat, struct sockaddr *addr, int new_por tmp_addr->sin6_port = port_mapped ? htons (nat->public_port) : 0; tmp_addr->sin6_addr = ((struct sockaddr_in6 *) nat->ext_addr)->sin6_addr; nat->contact_addr = (struct sockaddr *) tmp_addr; - if (nat->callback) - (*nat->callback) (nat->callback_cls, GNUNET_YES, nat->contact_addr, - sizeof (struct sockaddr_in6)); + if (NULL != nat->callback) + nat->callback (nat->callback_cls, + GNUNET_YES, + nat->contact_addr, + sizeof (struct sockaddr_in6)); + } + else + { + GNUNET_break (0); } } + static void -nat_pulse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +nat_pulse (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_NAT_Handle *nat = cls; - static int first_warning = GNUNET_YES; int old_status; int new_status; int port_mapped; struct sockaddr *ext_addr_upnp = NULL; struct sockaddr *ext_addr_natpmp = NULL; + nat->pulse_timer = GNUNET_SCHEDULER_NO_TASK; old_status = get_traversal_status (nat); /* Only update the protocol that has been successful until now */ @@ -230,6 +250,7 @@ nat_pulse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) &ext_addr_natpmp); else { + /* try both */ nat->upnp_status = GNUNET_NAT_UPNP_pulse (nat->upnp, nat->is_enabled, GNUNET_YES, &ext_addr_upnp); @@ -237,18 +258,17 @@ nat_pulse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_NAT_NATPMP_pulse (nat->natpmp, nat->is_enabled, &ext_addr_natpmp); } - new_status = get_traversal_status (nat); - - if (old_status != new_status && - (new_status == GNUNET_NAT_PORT_UNMAPPED || new_status == GNUNET_NAT_PORT_ERROR)) - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, COMP_NAT, + if ( (old_status != new_status) && + ( (new_status == GNUNET_NAT_PORT_UNMAPPED) || + (new_status == GNUNET_NAT_PORT_ERROR) ) ) + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, + "NAT", _("Port redirection failed: no UPnP or NAT-PMP routers supporting this feature found\n")); - #ifdef DEBUG if (new_status != old_status) - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, COMP_NAT, - _("State changed from \"%s\" to \"%s\"\n"), + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "NAT", + _("State changed from `%s' to `%s'\n"), get_nat_state_str (old_status), get_nat_state_str (new_status)); #endif @@ -257,53 +277,64 @@ nat_pulse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (!(ext_addr_upnp || ext_addr_natpmp)) { /* Address has just changed and we could not get it, or it's the first try */ - if (nat->ext_addr || first_warning) + if ( (NULL != nat->ext_addr) || + (GNUNET_NO == nat->did_warn) ) { - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, COMP_NAT, - _("Could not determine external IP address\n")); - first_warning = GNUNET_NO; + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, + "NAT", + _("Could not determine external IP address\n")); + nat->did_warn = GNUNET_YES; } - notify_change (nat, NULL, port_mapped); } else if (ext_addr_upnp && GNUNET_NAT_cmp_addr (nat->ext_addr, ext_addr_upnp) != 0) { - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, COMP_NAT, - _("External IP address changed from %s to %s\n"), - GNUNET_a2s (nat->ext_addr, sizeof (nat->ext_addr)), - GNUNET_a2s (ext_addr_upnp, sizeof (ext_addr_upnp))); - + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, + "NAT", + _("External IP address changed to %s\n"), + GNUNET_a2s (ext_addr_upnp, sizeof (ext_addr_upnp))); notify_change (nat, ext_addr_upnp, port_mapped); } else if (ext_addr_natpmp && GNUNET_NAT_cmp_addr (nat->ext_addr, ext_addr_natpmp) != 0) { - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, COMP_NAT, - _("External IP address changed from %s to %s\n"), - GNUNET_a2s (nat->ext_addr, sizeof (nat->ext_addr)), - GNUNET_a2s (ext_addr_natpmp, sizeof (ext_addr_natpmp))); - + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "NAT", + _("External IP address changed to `%s'\n"), + GNUNET_a2s (ext_addr_natpmp, sizeof (ext_addr_natpmp))); notify_change (nat, ext_addr_natpmp, port_mapped); } - nat->pulse_timer = GNUNET_SCHEDULER_add_delayed (nat->sched, GNUNET_TIME_UNIT_SECONDS, &nat_pulse, nat); } + +/** + * Attempt to enable port redirection and detect public IP address contacting + * UPnP or NAT-PMP routers on the local network. Use addr to specify to which + * of the local host's addresses should the external port be mapped. The port + * is taken from the corresponding sockaddr_in[6] field. + * + * @param sched the sheduler used in the program + * @param addr the local address packets should be redirected to + * @param addrlen actual lenght of the address + * @param callback function to call everytime the public IP address changes + * @param callback_cls closure for callback + * @return NULL on error, otherwise handle that can be used to unregister + */ struct GNUNET_NAT_Handle * GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, const struct sockaddr *addr, socklen_t addrlen, GNUNET_NAT_AddressCallback callback, void *callback_cls) { - struct GNUNET_NAT_Handle *nat = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); + struct GNUNET_NAT_Handle *nat; + nat = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); if (addr) { - GNUNET_assert (addr->sa_family == AF_INET - || addr->sa_family == AF_INET6); + GNUNET_assert ( (addr->sa_family == AF_INET) || + (addr->sa_family == AF_INET6) ); nat->local_addr = GNUNET_malloc (addrlen); memcpy (nat->local_addr, addr, addrlen); - if (addr->sa_family == AF_INET) { nat->public_port = ntohs (((struct sockaddr_in *) addr)->sin_port); @@ -315,12 +346,6 @@ GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, ((struct sockaddr_in6 *) nat->local_addr)->sin6_port = 0; } } - else - { - nat->local_addr = NULL; - nat->public_port = 0; - } - nat->should_change = GNUNET_YES; nat->sched = sched; nat->is_enabled = GNUNET_YES; @@ -328,37 +353,41 @@ GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, nat->natpmp_status = GNUNET_NAT_PORT_UNMAPPED; nat->callback = callback; nat->callback_cls = callback_cls; - nat->ext_addr = NULL; - nat->contact_addr = NULL; nat->natpmp = GNUNET_NAT_NATPMP_init (nat->local_addr, addrlen, nat->public_port); nat->upnp = GNUNET_NAT_UPNP_init (nat->local_addr, addrlen, nat->public_port); - nat->pulse_timer = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_UNIT_SECONDS, &nat_pulse, nat); - return nat; } + +/** + * Stop port redirection and public IP address detection for the given handle. + * This frees the handle, after having sent the needed commands to close open ports. + * + * @param h the handle to stop + */ void GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *nat) { struct sockaddr *addr; - GNUNET_SCHEDULER_cancel (nat->sched, nat->pulse_timer); + GNUNET_SCHEDULER_cancel (nat->sched, + nat->pulse_timer); nat->upnp_status = - GNUNET_NAT_UPNP_pulse (nat->upnp, GNUNET_NO, GNUNET_NO, + GNUNET_NAT_UPNP_pulse (nat->upnp, + GNUNET_NO, GNUNET_NO, &addr); nat->natpmp_status = GNUNET_NAT_NATPMP_pulse (nat->natpmp, GNUNET_NO, &addr); - GNUNET_NAT_NATPMP_close (nat->natpmp); GNUNET_NAT_UPNP_close (nat->upnp); - - if (nat->local_addr) - GNUNET_free (nat->local_addr); - if (nat->ext_addr) - GNUNET_free (nat->ext_addr); + GNUNET_free_non_null (nat->local_addr); + GNUNET_free_non_null (nat->ext_addr); GNUNET_free (nat); } + +/* end of nat.c */ + diff --git a/src/nat/natpmp.h b/src/nat/natpmp.h index 54afbf5f1..8e1531cee 100644 --- a/src/nat/natpmp.h +++ b/src/nat/natpmp.h @@ -30,15 +30,18 @@ #include "platform.h" -typedef struct GNUNET_NAT_NATPMP_Handle GNUNET_NAT_NATPMP_Handle; +struct GNUNET_NAT_NATPMP_Handle; -GNUNET_NAT_NATPMP_Handle *GNUNET_NAT_NATPMP_init (const struct sockaddr *addr, - socklen_t addrlen, - unsigned short port); +struct GNUNET_NAT_NATPMP_Handle * +GNUNET_NAT_NATPMP_init (const struct sockaddr *addr, + socklen_t addrlen, + unsigned short port); -void GNUNET_NAT_NATPMP_close (GNUNET_NAT_NATPMP_Handle * nat); +void GNUNET_NAT_NATPMP_close (struct GNUNET_NAT_NATPMP_Handle * nat); -int GNUNET_NAT_NATPMP_pulse (GNUNET_NAT_NATPMP_Handle * nat, int is_enabled, +int GNUNET_NAT_NATPMP_pulse (struct GNUNET_NAT_NATPMP_Handle * nat, + int is_enabled, struct sockaddr **ext_addr); -#endif /* NATPMP_H */ +#endif +/* NATPMP_H */ diff --git a/src/nat/upnp.c b/src/nat/upnp.c index 8fc5f7e04..84abe339d 100644 --- a/src/nat/upnp.c +++ b/src/nat/upnp.c @@ -46,15 +46,14 @@ /* Component name for logging */ #define COMP_NAT_UPNP _("NAT (UPnP)") -typedef enum +enum UPNP_State { UPNP_IDLE, UPNP_ERR, UPNP_DISCOVER, UPNP_MAP, UPNP_UNMAP -} -UPNP_state; +}; struct GNUNET_NAT_UPNP_Handle { @@ -65,7 +64,7 @@ struct GNUNET_NAT_UPNP_Handle const struct sockaddr *addr; socklen_t addrlen; unsigned int is_mapped; - UPNP_state state; + enum UPNP_State state; struct sockaddr *ext_addr; const char *iface; }; @@ -81,35 +80,37 @@ process_if (void *cls, if (addr && GNUNET_NAT_cmp_addr (upnp->addr, addr) == 0) { - upnp->iface = name; + upnp->iface = name; // BADNESS! return GNUNET_SYSERR; } return GNUNET_OK; } + GNUNET_NAT_UPNP_Handle * -GNUNET_NAT_UPNP_init (const struct sockaddr *addr, socklen_t addrlen, +GNUNET_NAT_UPNP_init (const struct sockaddr *addr, + socklen_t addrlen, u_short port) { - GNUNET_NAT_UPNP_Handle *upnp = - GNUNET_malloc (sizeof (GNUNET_NAT_UPNP_Handle)); + GNUNET_NAT_UPNP_Handle *upnp; + upnp = GNUNET_malloc (sizeof (GNUNET_NAT_UPNP_Handle)); upnp->state = UPNP_DISCOVER; upnp->addr = addr; upnp->addrlen = addrlen; upnp->port = port; - /* Find the interface corresponding to the address, * on which we should broadcast call for routers */ - upnp->iface = NULL; - GNUNET_OS_network_interfaces_list (process_if, upnp); + GNUNET_OS_network_interfaces_list (&process_if, upnp); if (!upnp->iface) - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, COMP_NAT_UPNP, "Could not find an interface matching the wanted address.\n"); - + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, + COMP_NAT_UPNP, + "Could not find an interface matching the wanted address.\n"); return upnp; } + void GNUNET_NAT_UPNP_close (GNUNET_NAT_UPNP_Handle * handle) { diff --git a/src/nat/upnp.h b/src/nat/upnp.h index 8fd44a8f1..ccb04ed00 100644 --- a/src/nat/upnp.h +++ b/src/nat/upnp.h @@ -30,14 +30,19 @@ #include "platform.h" -typedef struct GNUNET_NAT_UPNP_Handle GNUNET_NAT_UPNP_Handle; +struct GNUNET_NAT_UPNP_Handle; -GNUNET_NAT_UPNP_Handle *GNUNET_NAT_UPNP_init (const struct sockaddr *addr, - socklen_t addrlen, - unsigned short port); +struct GNUNET_NAT_UPNP_Handle * +GNUNET_NAT_UPNP_init (const struct sockaddr *addr, + socklen_t addrlen, + unsigned short port); -void GNUNET_NAT_UPNP_close (GNUNET_NAT_UPNP_Handle *); +void GNUNET_NAT_UPNP_close (struct GNUNET_NAT_UPNP_Handle * h); -int GNUNET_NAT_UPNP_pulse (GNUNET_NAT_UPNP_Handle *, int is_enabled, - int do_port_check, struct sockaddr **ext_addr); -#endif /* UPNP_H */ +int GNUNET_NAT_UPNP_pulse (struct GNUNET_NAT_UPNP_Handle *h, + int is_enabled, + int do_port_check, + struct sockaddr **ext_addr); + +#endif +/* UPNP_H */ -- cgit v1.2.3