From 69486b105944dbeb528b0c78e3cbe44e4c7cc657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 14 Mar 2021 12:07:28 +0100 Subject: [PATCH] miniupnpc: Update to version 2.2.2 --- COPYRIGHT.txt | 2 +- modules/upnp/SCsub | 19 +- thirdparty/README.md | 13 +- thirdparty/miniupnpc/LICENSE | 5 +- .../miniupnpc/miniupnpc/addr_is_reserved.c | 79 ++ .../miniupnpc/miniupnpc/addr_is_reserved.h | 14 + .../miniupnpc/miniupnpc/connecthostport.c | 6 +- thirdparty/miniupnpc/miniupnpc/listdevices.c | 197 ---- thirdparty/miniupnpc/miniupnpc/minisoap.c | 6 +- thirdparty/miniupnpc/miniupnpc/minissdpc.c | 232 +++-- thirdparty/miniupnpc/miniupnpc/miniupnpc.c | 35 +- thirdparty/miniupnpc/miniupnpc/miniupnpc.h | 6 +- .../miniupnpc/miniupnpc/miniupnpc_socketdef.h | 2 +- .../miniupnpc/miniupnpc/miniupnpcmodule.c | 721 --------------- .../miniupnpc/miniupnpc/miniupnpcstrings.h | 2 +- thirdparty/miniupnpc/miniupnpc/miniwget.c | 15 +- .../miniupnpc/miniupnpc/portlistingparse.c | 2 +- thirdparty/miniupnpc/miniupnpc/receivedata.c | 10 +- thirdparty/miniupnpc/miniupnpc/upnpc.c | 864 ------------------ thirdparty/miniupnpc/miniupnpc/upnpdev.h | 16 +- thirdparty/miniupnpc/miniupnpc/upnperrors.c | 112 --- thirdparty/miniupnpc/miniupnpc/upnperrors.h | 26 - .../miniupnpc/miniupnpc/win32_snprintf.h | 71 ++ 23 files changed, 386 insertions(+), 2069 deletions(-) create mode 100644 thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c create mode 100644 thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h delete mode 100644 thirdparty/miniupnpc/miniupnpc/listdevices.c delete mode 100644 thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c delete mode 100644 thirdparty/miniupnpc/miniupnpc/upnpc.c delete mode 100644 thirdparty/miniupnpc/miniupnpc/upnperrors.c delete mode 100644 thirdparty/miniupnpc/miniupnpc/upnperrors.h create mode 100644 thirdparty/miniupnpc/miniupnpc/win32_snprintf.h diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index ff24d18e6f..96aedccd7f 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -269,7 +269,7 @@ License: CC0-1.0 Files: ./thirdparty/miniupnpc/ Comment: MiniUPnPc -Copyright: 2005-2019, Thomas Bernard +Copyright: 2005-2021, Thomas Bernard License: BSD-3-clause Files: ./thirdparty/minizip/ diff --git a/modules/upnp/SCsub b/modules/upnp/SCsub index bc0b215be3..b2fed0cb23 100644 --- a/modules/upnp/SCsub +++ b/modules/upnp/SCsub @@ -12,18 +12,19 @@ thirdparty_obj = [] if env["builtin_miniupnpc"]: thirdparty_dir = "#thirdparty/miniupnpc/" thirdparty_sources = [ - "miniupnpc.c", - "upnpcommands.c", - "miniwget.c", - "upnpdev.c", "igd_desc_parse.c", - "minissdpc.c", - "minisoap.c", + "miniupnpc.c", "minixml.c", - "connecthostport.c", - "receivedata.c", - "portlistingparse.c", + "minisoap.c", + "minissdpc.c", + "miniwget.c", + "upnpcommands.c", + "upnpdev.c", "upnpreplyparse.c", + "connecthostport.c", + "portlistingparse.c", + "receivedata.c", + "addr_is_reserved.c", ] thirdparty_sources = [thirdparty_dir + "miniupnpc/" + file for file in thirdparty_sources] diff --git a/thirdparty/README.md b/thirdparty/README.md index 0eb227d0f9..537f3d218f 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -355,17 +355,20 @@ Files extracted from upstream repository: ## miniupnpc -- Upstream: https://github.com/miniupnp/miniupnp/tree/master/miniupnpc -- Version: git (44366328661826603982d1e0d7ebb4062c5f2bfc, 2020) +- Upstream: https://github.com/miniupnp/miniupnp +- Version: 2.2.2 (81029a860baf1f727903e5b85307903b3f40cbc8, 2021) - License: BSD-3-Clause Files extracted from upstream source: - All `*.c` and `*.h` files from `miniupnpc` to `thirdparty/miniupnpc/miniupnpc` -- Remove `test*`, `minihttptestserver.c` and `wingenminiupnpcstrings.c` +- Remove the following test or sample files: + `listdevices.c minihttptestserver.c miniupnpcmodule.c upnpc.c upnperrors.* test* wingenminiupnpcstrings.c` +- `LICENSE` -The only modified file is miniupnpcstrings.h, which was created for Godot -(it is usually autogenerated by cmake). +The only modified file is `miniupnpcstrings.h`, which was created for Godot +(it is usually autogenerated by cmake). Bump the version number for miniupnpc in that +file when upgrading. ## minizip diff --git a/thirdparty/miniupnpc/LICENSE b/thirdparty/miniupnpc/LICENSE index 1460310752..6ddd381baa 100644 --- a/thirdparty/miniupnpc/LICENSE +++ b/thirdparty/miniupnpc/LICENSE @@ -1,5 +1,5 @@ -MiniUPnP Project -Copyright (c) 2005-2019, Thomas BERNARD +MiniUPnPc +Copyright (c) 2005-2020, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without @@ -24,3 +24,4 @@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c new file mode 100644 index 0000000000..7e586d7da2 --- /dev/null +++ b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c @@ -0,0 +1,79 @@ +/* $Id: addr_is_reserved.c,v 1.4 2021/03/02 23:40:32 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ + * Author : Thomas BERNARD + * copyright (c) 2005-2021 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENSE file. */ +#ifdef _WIN32 +/* Win32 Specific includes and defines */ +#include +#include +#if !defined(_MSC_VER) +#include +#else /* !defined(_MSC_VER) */ +typedef unsigned long uint32_t; +#endif /* !defined(_MSC_VER) */ +#else /* _WIN32 */ +#include +#include +#include +#include +#endif /* _WIN32 */ + +/* List of IP address blocks which are private / reserved and therefore not suitable for public external IP addresses */ +#define IP(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) +#define MSK(m) (32-(m)) +static const struct { uint32_t address; uint32_t rmask; } reserved[] = { + { IP( 0, 0, 0, 0), MSK( 8) }, /* RFC1122 "This host on this network" */ + { IP( 10, 0, 0, 0), MSK( 8) }, /* RFC1918 Private-Use */ + { IP(100, 64, 0, 0), MSK(10) }, /* RFC6598 Shared Address Space */ + { IP(127, 0, 0, 0), MSK( 8) }, /* RFC1122 Loopback */ + { IP(169, 254, 0, 0), MSK(16) }, /* RFC3927 Link-Local */ + { IP(172, 16, 0, 0), MSK(12) }, /* RFC1918 Private-Use */ + { IP(192, 0, 0, 0), MSK(24) }, /* RFC6890 IETF Protocol Assignments */ + { IP(192, 0, 2, 0), MSK(24) }, /* RFC5737 Documentation (TEST-NET-1) */ + { IP(192, 31, 196, 0), MSK(24) }, /* RFC7535 AS112-v4 */ + { IP(192, 52, 193, 0), MSK(24) }, /* RFC7450 AMT */ + { IP(192, 88, 99, 0), MSK(24) }, /* RFC7526 6to4 Relay Anycast */ + { IP(192, 168, 0, 0), MSK(16) }, /* RFC1918 Private-Use */ + { IP(192, 175, 48, 0), MSK(24) }, /* RFC7534 Direct Delegation AS112 Service */ + { IP(198, 18, 0, 0), MSK(15) }, /* RFC2544 Benchmarking */ + { IP(198, 51, 100, 0), MSK(24) }, /* RFC5737 Documentation (TEST-NET-2) */ + { IP(203, 0, 113, 0), MSK(24) }, /* RFC5737 Documentation (TEST-NET-3) */ + { IP(224, 0, 0, 0), MSK( 4) }, /* RFC1112 Multicast */ + { IP(240, 0, 0, 0), MSK( 4) }, /* RFC1112 Reserved for Future Use + RFC919 Limited Broadcast */ +}; +#undef IP +#undef MSK + +/** + * @return 1 or 0 + */ +int addr_is_reserved(const char * addr_str) +{ + uint32_t addr_n, address; + size_t i; + +#if defined(_WIN32) && (!defined(_WIN32_WINNT_VISTA) || (_WIN32_WINNT < _WIN32_WINNT_VISTA)) + addr_n = inet_addr(addr_str); + if (addr_n == INADDR_NONE) + return 1; +#else + /* was : addr_n = inet_addr(addr_str); */ + if (inet_pton(AF_INET, addr_str, &addr_n) <= 0) { + /* error */ + return 1; + } +#endif + + address = ntohl(addr_n); + + for (i = 0; i < sizeof(reserved)/sizeof(reserved[0]); ++i) { + if ((address >> reserved[i].rmask) == (reserved[i].address >> reserved[i].rmask)) + return 1; + } + + return 0; +} diff --git a/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h new file mode 100644 index 0000000000..f8b5d66a09 --- /dev/null +++ b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h @@ -0,0 +1,14 @@ +/* $Id: $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project: miniupnp + * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2020 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef ADDR_IS_RESERVED_H_INCLUDED +#define ADDR_IS_RESERVED_H_INCLUDED + +int addr_is_reserved(const char * addr_str); + +#endif /* ADDR_IS_RESERVED_H_INCLUDED */ diff --git a/thirdparty/miniupnpc/miniupnpc/connecthostport.c b/thirdparty/miniupnpc/miniupnpc/connecthostport.c index f3982e1a77..79f832b8db 100644 --- a/thirdparty/miniupnpc/miniupnpc/connecthostport.c +++ b/thirdparty/miniupnpc/miniupnpc/connecthostport.c @@ -1,8 +1,8 @@ -/* $Id: connecthostport.c,v 1.22 2019/10/13 17:22:08 nanard Exp $ */ +/* $Id: connecthostport.c,v 1.24 2020/11/09 19:26:53 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2010-2019 Thomas Bernard + * Copyright (c) 2010-2020 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -19,7 +19,7 @@ #include #include #define MAXHOSTNAMELEN 64 -#define snprintf _snprintf +#include "win32_snprintf.h" #define herror #define socklen_t int #else /* #ifdef _WIN32 */ diff --git a/thirdparty/miniupnpc/miniupnpc/listdevices.c b/thirdparty/miniupnpc/miniupnpc/listdevices.c deleted file mode 100644 index bd9ba57efc..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/listdevices.c +++ /dev/null @@ -1,197 +0,0 @@ -/* $Id: listdevices.c,v 1.6 2015/07/23 20:40:08 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2013-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#include -#ifdef _WIN32 -#include -#endif /* _WIN32 */ -#include "miniupnpc.h" - -struct upnp_dev_list { - struct upnp_dev_list * next; - char * descURL; - struct UPNPDev * * array; - size_t count; - size_t allocated_count; -}; - -#define ADD_DEVICE_COUNT_STEP 16 - -void add_device(struct upnp_dev_list * * list_head, struct UPNPDev * dev) -{ - struct upnp_dev_list * elt; - size_t i; - - if(dev == NULL) - return; - for(elt = *list_head; elt != NULL; elt = elt->next) { - if(strcmp(elt->descURL, dev->descURL) == 0) { - for(i = 0; i < elt->count; i++) { - if (strcmp(elt->array[i]->st, dev->st) == 0 && strcmp(elt->array[i]->usn, dev->usn) == 0) { - return; /* already found */ - } - } - if(elt->count >= elt->allocated_count) { - struct UPNPDev * * tmp; - elt->allocated_count += ADD_DEVICE_COUNT_STEP; - tmp = realloc(elt->array, elt->allocated_count * sizeof(struct UPNPDev *)); - if(tmp == NULL) { - fprintf(stderr, "Failed to realloc(%p, %lu)\n", elt->array, (unsigned long)(elt->allocated_count * sizeof(struct UPNPDev *))); - return; - } - elt->array = tmp; - } - elt->array[elt->count++] = dev; - return; - } - } - elt = malloc(sizeof(struct upnp_dev_list)); - if(elt == NULL) { - fprintf(stderr, "Failed to malloc(%lu)\n", (unsigned long)sizeof(struct upnp_dev_list)); - return; - } - elt->next = *list_head; - elt->descURL = strdup(dev->descURL); - if(elt->descURL == NULL) { - fprintf(stderr, "Failed to strdup(%s)\n", dev->descURL); - free(elt); - return; - } - elt->allocated_count = ADD_DEVICE_COUNT_STEP; - elt->array = malloc(ADD_DEVICE_COUNT_STEP * sizeof(struct UPNPDev *)); - if(elt->array == NULL) { - fprintf(stderr, "Failed to malloc(%lu)\n", (unsigned long)(ADD_DEVICE_COUNT_STEP * sizeof(struct UPNPDev *))); - free(elt->descURL); - free(elt); - return; - } - elt->array[0] = dev; - elt->count = 1; - *list_head = elt; -} - -void free_device(struct upnp_dev_list * elt) -{ - free(elt->descURL); - free(elt->array); - free(elt); -} - -int main(int argc, char * * argv) -{ - const char * searched_device = NULL; - const char * * searched_devices = NULL; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int ipv6 = 0; - unsigned char ttl = 2; - int error = 0; - struct UPNPDev * devlist = 0; - struct UPNPDev * dev; - struct upnp_dev_list * sorted_list = NULL; - struct upnp_dev_list * dev_array; - int i; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - - for(i = 1; i < argc; i++) { - if(strcmp(argv[i], "-6") == 0) - ipv6 = 1; - else if(strcmp(argv[i], "-d") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-d"); - return 1; - } - searched_device = argv[i]; - } else if(strcmp(argv[i], "-t") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-t"); - return 1; - } - ttl = (unsigned char)atoi(argv[i]); - } else if(strcmp(argv[i], "-l") == 0) { - if(++i >= argc) { - fprintf(stderr, "-l option needs at least one argument\n"); - return 1; - } - searched_devices = (const char * *)(argv + i); - break; - } else if(strcmp(argv[i], "-m") == 0) { - if(++i >= argc) { - fprintf(stderr, "-m option needs one argument\n"); - return 1; - } - multicastif = argv[i]; - } else { - printf("usage : %s [options] [-l ...]\n", argv[0]); - printf("options :\n"); - printf(" -6 : use IPv6\n"); - printf(" -m address/ifname : network interface to use for multicast\n"); - printf(" -d : search only for this type of device\n"); - printf(" -l ... : search only for theses types of device\n"); - printf(" -t ttl : set multicast TTL. Default value is 2.\n"); - printf(" -h : this help\n"); - return 1; - } - } - - if(searched_device) { - printf("searching UPnP device type %s\n", searched_device); - devlist = upnpDiscoverDevice(searched_device, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } else if(searched_devices) { - printf("searching UPnP device types :\n"); - for(i = 0; searched_devices[i]; i++) - printf("\t%s\n", searched_devices[i]); - devlist = upnpDiscoverDevices(searched_devices, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error, 1); - } else { - printf("searching all UPnP devices\n"); - devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } - if(devlist) { - for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) { - printf("%3d: %-48s\n", i, dev->st); - printf(" %s\n", dev->descURL); - printf(" %s\n", dev->usn); - add_device(&sorted_list, dev); - } - putchar('\n'); - for (dev_array = sorted_list; dev_array != NULL ; dev_array = dev_array->next) { - printf("%s :\n", dev_array->descURL); - for(i = 0; (unsigned)i < dev_array->count; i++) { - printf("%2d: %s\n", i+1, dev_array->array[i]->st); - printf(" %s\n", dev_array->array[i]->usn); - } - putchar('\n'); - } - freeUPNPDevlist(devlist); - while(sorted_list != NULL) { - dev_array = sorted_list; - sorted_list = sorted_list->next; - free_device(dev_array); - } - } else { - printf("no device found.\n"); - } - - return 0; -} - diff --git a/thirdparty/miniupnpc/miniupnpc/minisoap.c b/thirdparty/miniupnpc/miniupnpc/minisoap.c index f92b36ce89..78606672d5 100644 --- a/thirdparty/miniupnpc/miniupnpc/minisoap.c +++ b/thirdparty/miniupnpc/miniupnpc/minisoap.c @@ -1,8 +1,8 @@ -/* $Id: minisoap.c,v 1.25 2017/04/21 10:03:24 nanard Exp $ */ +/* $Id: minisoap.c,v 1.30 2020/11/09 19:27:42 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2018 Thomas Bernard + * Copyright (c) 2005-2020 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * @@ -13,7 +13,7 @@ #ifdef _WIN32 #include #include -#define snprintf _snprintf +#include "win32_snprintf.h" #else #include #include diff --git a/thirdparty/miniupnpc/miniupnpc/minissdpc.c b/thirdparty/miniupnpc/miniupnpc/minissdpc.c index a3b1283da5..0ef7e12cfb 100644 --- a/thirdparty/miniupnpc/miniupnpc/minissdpc.c +++ b/thirdparty/miniupnpc/miniupnpc/minissdpc.c @@ -1,15 +1,15 @@ -/* $Id: minissdpc.c,v 1.40 2019/04/23 12:12:55 nanard Exp $ */ +/* $Id: minissdpc.c,v 1.47 2021/03/02 23:38:30 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp - * Web : http://miniupnp.free.fr/ + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2019 Thomas Bernard + * copyright (c) 2005-2021 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ -/*#include */ #include #include #include +#include #include #if defined (__NetBSD__) #include @@ -20,7 +20,7 @@ #include #include #include -#define snprintf _snprintf +#include "win32_snprintf.h" #if !defined(_MSC_VER) #include #else /* !defined(_MSC_VER) */ @@ -33,6 +33,12 @@ typedef unsigned short uint16_t; #define strncasecmp memicmp #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* #ifndef strncasecmp */ +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP +#define in6addr_any in6addr_any_init +static const IN6_ADDR in6addr_any_init = {0}; +#endif +#endif #endif /* _WIN32 */ #if defined(__amigaos__) || defined(__amigaos4__) #include @@ -66,7 +72,7 @@ struct sockaddr_un { #define HAS_IP_MREQN #endif -#if !defined(HAS_IP_MREQN) && !defined(_WIN32) +#ifndef _WIN32 #include #if defined(__sun) || defined(__HAIKU__) #include @@ -445,6 +451,36 @@ parseMSEARCHReply(const char * reply, int size, } } +#if defined(CLOCK_MONOTONIC_FAST) +#define UPNP_CLOCKID CLOCK_MONOTONIC_FAST +#elif defined(CLOCK_MONOTONIC) +#define UPNP_CLOCKID CLOCK_MONOTONIC +#endif + +static int upnp_gettimeofday(struct timeval * tv) +{ +#if defined(_WIN32) +#if defined(_WIN32_WINNT_VISTA) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) + ULONGLONG ts = GetTickCount64(); +#else + DWORD ts = GetTickCount(); +#endif + tv->tv_sec = (long)(ts / 1000); + tv->tv_usec = (ts % 1000) * 1000; + return 0; /* success */ +#elif defined(CLOCK_MONOTONIC_FAST) || defined(CLOCK_MONOTONIC) + struct timespec ts; + int ret_code = clock_gettime(UPNP_CLOCKID, &ts); + if (ret_code == 0) + { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + } + return ret_code; +#else + return gettimeofday(tv, NULL); +#endif +} /* port upnp discover : SSDP protocol */ #define SSDP_PORT 1900 #define XSTR(s) STR(s) @@ -540,12 +576,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ if(!ipv6) { DWORD ifbestidx; - SOCKADDR_IN destAddr; - memset(&destAddr, 0, sizeof(destAddr)); - destAddr.sin_family = AF_INET; - destAddr.sin_addr.s_addr = inet_addr("223.255.255.255"); - destAddr.sin_port = 0; - if (GetBestInterfaceEx((struct sockaddr *)&destAddr, &ifbestidx) == NO_ERROR) { + if (GetBestInterface(inet_addr("223.255.255.255"), &ifbestidx) == NO_ERROR) { DWORD dwRetVal = NO_ERROR; PIP_ADAPTER_ADDRESSES pAddresses = NULL; ULONG outBufLen = 15360; @@ -672,6 +703,13 @@ ssdpDiscoverDevices(const char * const deviceTypes[], * MS Windows Vista and MS Windows Server 2008. * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ + if(ifindex == 0) + { + if(error) + *error = MINISSDPC_INVALID_INPUT; + fprintf(stderr, "Invalid multicast interface name %s\n", multicastif); + goto error; + } if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) { PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF"); @@ -683,10 +721,17 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif } else { struct in_addr mc_if; -#if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) +#if defined(_WIN32) +#if defined(_WIN32_WINNT_VISTA) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) InetPtonA(AF_INET, multicastif, &mc_if); #else - mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ + mc_if.s_addr = inet_addr(multicastif); /* old Windows SDK do not support InetPtoA() */ +#endif +#else + /* was : mc_if.s_addr = inet_addr(multicastif); */ /* ex: 192.168.x.x */ + if (inet_pton(AF_INET, multicastif, &mc_if.s_addr) <= 0) { + mc_if.s_addr = INADDR_NONE; + } #endif if(mc_if.s_addr != INADDR_NONE) { @@ -696,16 +741,11 @@ ssdpDiscoverDevices(const char * const deviceTypes[], PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } } else { -#ifdef HAS_IP_MREQN /* was not an ip address, try with an interface name */ +#ifndef _WIN32 +#ifdef HAS_IP_MREQN struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ - memset(&reqn, 0, sizeof(struct ip_mreqn)); - reqn.imr_ifindex = if_nametoindex(multicastif); - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#elif !defined(_WIN32) +#endif struct ifreq ifr; int ifrlen = sizeof(ifr); strncpy(ifr.ifr_name, multicastif, IFNAMSIZ); @@ -713,12 +753,30 @@ ssdpDiscoverDevices(const char * const deviceTypes[], if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0) { PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)"); + goto error; } mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; +#ifdef HAS_IP_MREQN + memset(&reqn, 0, sizeof(struct ip_mreqn)); + reqn.imr_address.s_addr = mc_if.s_addr; + reqn.imr_ifindex = if_nametoindex(multicastif); + if(reqn.imr_ifindex == 0) + { + if(error) + *error = MINISSDPC_INVALID_INPUT; + fprintf(stderr, "Invalid multicast ip address / interface name %s\n", multicastif); + goto error; + } + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); + } +#else if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } +#endif #else /* _WIN32 */ #ifdef DEBUG printf("Setting of multicast interface not supported with interface name.\n"); @@ -842,73 +900,84 @@ ssdpDiscoverDevices(const char * const deviceTypes[], /* Waiting for SSDP REPLY packet to M-SEARCH * if searchalltypes is set, enter the loop only * when the last deviceType is reached */ - if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { - n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); - if (n < 0) { - /* error */ - if(error) - *error = MINISSDPC_SOCKET_ERROR; - goto error; - } else if (n == 0) { - /* no data or Time Out */ -#ifdef DEBUG - printf("NODATA or TIMEOUT\n"); -#endif /* DEBUG */ - if (devlist && !searchalltypes) { - /* found some devices, stop now*/ + if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) { + struct timeval start = {0, 0}, current = {0, 0}; + upnp_gettimeofday(&start); + do { + n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); + if (n < 0) { + /* error */ if(error) - *error = MINISSDPC_SUCCESS; + *error = MINISSDPC_SOCKET_ERROR; goto error; - } - } else { - const char * descURL=NULL; - int urlsize=0; - const char * st=NULL; - int stsize=0; - const char * usn=NULL; - int usnsize=0; - parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); - if(st&&descURL) { + } else if (n == 0) { + /* no data or Time Out */ #ifdef DEBUG - printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", - stsize, st, usnsize, (usn?usn:""), urlsize, descURL); + printf("NODATA or TIMEOUT\n"); #endif /* DEBUG */ - for(tmp=devlist; tmp; tmp = tmp->pNext) { - if(strncmp(tmp->descURL, descURL, urlsize) == 0 && - tmp->descURL[urlsize] == '\0' && - strncmp(tmp->st, st, stsize) == 0 && - tmp->st[stsize] == '\0' && - (usnsize == 0 || strncmp(tmp->usn, usn, usnsize) == 0) && - tmp->usn[usnsize] == '\0') - break; - } - /* at the exit of the loop above, tmp is null if - * no duplicate device was found */ - if(tmp) - continue; - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(!tmp) { - /* memory allocation error */ + if (devlist && !searchalltypes) { + /* found some devices, stop now*/ if(error) - *error = MINISSDPC_MEMORY_ERROR; + *error = MINISSDPC_SUCCESS; goto error; } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - tmp->usn = tmp->st + 1 + stsize; - memcpy(tmp->buffer, descURL, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - if(usn != NULL) - memcpy(tmp->usn, usn, usnsize); - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = scope_id; - devlist = tmp; + } else { + const char * descURL=NULL; + int urlsize=0; + const char * st=NULL; + int stsize=0; + const char * usn=NULL; + int usnsize=0; + parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); + if(st&&descURL) { +#ifdef DEBUG + printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", + stsize, st, usnsize, (usn?usn:""), urlsize, descURL); +#endif /* DEBUG */ + for(tmp=devlist; tmp; tmp = tmp->pNext) { + if(strncmp(tmp->descURL, descURL, urlsize) == 0 && + tmp->descURL[urlsize] == '\0' && + strncmp(tmp->st, st, stsize) == 0 && + tmp->st[stsize] == '\0' && + (usnsize == 0 || strncmp(tmp->usn, usn, usnsize) == 0) && + tmp->usn[usnsize] == '\0') + break; + } + /* at the exit of the loop above, tmp is null if + * no duplicate device was found */ + if(tmp) + continue; + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize+3); + if(!tmp) { + /* memory allocation error */ + if(error) + *error = MINISSDPC_MEMORY_ERROR; + goto error; + } + tmp->pNext = devlist; + tmp->descURL = tmp->buffer; + tmp->st = tmp->buffer + 1 + urlsize; + tmp->usn = tmp->st + 1 + stsize; + memcpy(tmp->buffer, descURL, urlsize); + tmp->buffer[urlsize] = '\0'; + memcpy(tmp->st, st, stsize); + tmp->buffer[urlsize+1+stsize] = '\0'; + if(usn != NULL) + memcpy(tmp->usn, usn, usnsize); + tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; + tmp->scope_id = scope_id; + devlist = tmp; + } + if (upnp_gettimeofday(¤t) >= 0) { + /* exit the loop if delay is reached */ + long interval = (current.tv_sec - start.tv_sec) * 1000; + interval += (current.tv_usec - start.tv_usec) / 1000; + if (interval > (long)delay) + break; + } } - } - } while(n > 0); + } while(n > 0); + } if(ipv6) { /* switch linklocal flag */ if(linklocal) { @@ -923,4 +992,3 @@ error: closesocket(sudp); return devlist; } - diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpc.c b/thirdparty/miniupnpc/miniupnpc/miniupnpc.c index 95ab6cf56b..696af93237 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpc.c +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpc.c @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.c,v 1.154 2019/04/23 12:12:13 nanard Exp $ */ +/* $Id: miniupnpc.c,v 1.159 2021/03/02 23:36:32 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp - * Web : http://miniupnp.free.fr/ + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2019 Thomas Bernard + * copyright (c) 2005-2021 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #include @@ -15,7 +15,7 @@ #include #include #include -#define snprintf _snprintf +#include "win32_snprintf.h" #define strdup _strdup #ifndef strncasecmp #if defined(_MSC_VER) && (_MSC_VER >= 1400) @@ -61,6 +61,7 @@ #include "minixml.h" #include "upnpcommands.h" #include "connecthostport.h" +#include "addr_is_reserved.h" /* compare the beginning of a string with a constant string */ #define COMPARE(str, cstr) (0==strncmp(str, cstr, sizeof(cstr) - 1)) @@ -73,24 +74,6 @@ #define SERVICEPREFIX "u" #define SERVICEPREFIX2 'u' -/* check if an ip address is a private (LAN) address - * see https://tools.ietf.org/html/rfc1918 */ -static int is_rfc1918addr(const char * addr) -{ - /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ - if(COMPARE(addr, "192.168.")) - return 1; - /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ - if(COMPARE(addr, "10.")) - return 1; - /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ - if(COMPARE(addr, "172.")) { - if((atoi(addr + 4) | 0x0f) == 0x1f) - return 1; - } - return 0; -} - /* root description parsing */ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) { @@ -337,6 +320,8 @@ upnpDiscoverDevices(const char * const deviceTypes[], return devlist; } } +#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ + (void)minissdpdsock; /* unused */ #endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ /* direct discovery if minissdpd responses are not sufficient */ @@ -643,8 +628,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, /* checks that status is connected AND there is a external IP address assigned */ if(is_connected && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) + if(!addr_is_reserved(extIpAddr)) goto free_and_return; } FreeUPNPUrls(urls); @@ -665,8 +649,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, #endif if(is_connected && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) + if(!addr_is_reserved(extIpAddr)) goto free_and_return; } FreeUPNPUrls(urls); diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpc.h b/thirdparty/miniupnpc/miniupnpc/miniupnpc.h index 8ddc282bd1..3aef8ea443 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpc.h +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpc.h @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.h,v 1.53 2018/05/07 11:05:16 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.58 2021/03/02 23:49:52 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project: miniupnp * http://miniupnp.free.fr/ * Author: Thomas Bernard - * Copyright (c) 2005-2018 Thomas Bernard + * Copyright (c) 2005-2021 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ #ifndef MINIUPNPC_H_INCLUDED @@ -20,7 +20,7 @@ #define UPNPDISCOVER_MEMORY_ERROR (-102) /* versions : */ -#define MINIUPNPC_VERSION "2.1" +#define MINIUPNPC_VERSION "2.2.2" #define MINIUPNPC_API_VERSION 17 /* Source port: diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h b/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h index d4f79a7bd6..5986e58c76 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h @@ -7,7 +7,7 @@ #ifndef MINIUPNPC_SOCKETDEF_H_INCLUDED #define MINIUPNPC_SOCKETDEF_H_INCLUDED -#ifdef _MSC_VER +#ifdef _WIN32 #define ISINVALID(s) (INVALID_SOCKET==(s)) diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c b/thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c deleted file mode 100644 index d9341ab5bf..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c +++ /dev/null @@ -1,721 +0,0 @@ -/* $Id: miniupnpcmodule.c,v 1.34 2019/05/20 19:07:16 nanard Exp $*/ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Author : Thomas BERNARD - * website : https://miniupnp.tuxfamily.org/ - * copyright (c) 2007-2019 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#define MINIUPNP_STATICLIB -#include "structmember.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" - -#ifdef _WIN32 -#include -#endif - -/* for compatibility with Python < 2.4 */ -#ifndef Py_RETURN_NONE -#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None -#endif - -#ifndef Py_RETURN_TRUE -#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True -#endif - -#ifndef Py_RETURN_FALSE -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False -#endif - -/* for compatibility with Python < 3.0 */ -#ifndef PyVarObject_HEAD_INIT -#define PyVarObject_HEAD_INIT(type, size) \ - PyObject_HEAD_INIT(type) size, -#endif - -#ifndef Py_TYPE -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) -#endif - -typedef struct { - PyObject_HEAD - /* Type-specific fields go here. */ - struct UPNPDev * devlist; - struct UPNPUrls urls; - struct IGDdatas data; - unsigned int discoverdelay; /* value passed to upnpDiscover() */ - unsigned int localport; /* value passed to upnpDiscover() */ - char lanaddr[40]; /* our ip address on the LAN */ - char * multicastif; - char * minissdpdsocket; -} UPnPObject; - -static PyMemberDef UPnP_members[] = { - {"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr), - READONLY, "ip address on the LAN" - }, - {"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay), - 0/*READWRITE*/, "value in ms used to wait for SSDP responses" - }, - {"localport", T_UINT, offsetof(UPnPObject, localport), - 0/*READWRITE*/, - "If localport is set to UPNP_LOCAL_PORT_SAME(1) " - "SSDP packets will be sent from the source port " - "1900 (same as destination port), if set to " - "UPNP_LOCAL_PORT_ANY(0) system assign a source " - "port, any other value will be attempted as the " - "source port" - }, - /* T_STRING is allways readonly :( */ - {"multicastif", T_STRING, offsetof(UPnPObject, multicastif), - 0, "IP of the network interface to be used for multicast operations" - }, - {"minissdpdsocket", T_STRING, offsetof(UPnPObject, minissdpdsocket), - 0, "path of the MiniSSDPd unix socket" - }, - {NULL} -}; - - -static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds) -{ - char* multicastif = NULL; - char* minissdpdsocket = NULL; - static char *kwlist[] = { - "multicastif", "minissdpdsocket", "discoverdelay", - "localport", NULL - }; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist, - &multicastif, - &minissdpdsocket, - &self->discoverdelay, - &self->localport)) - return -1; - - if(self->localport>1 && - (self->localport>65534||self->localport<1024)) { - PyErr_SetString(PyExc_Exception, "Invalid localport value"); - return -1; - } - if(multicastif) - self->multicastif = strdup(multicastif); - if(minissdpdsocket) - self->minissdpdsocket = strdup(minissdpdsocket); - - return 0; -} - -static void -UPnPObject_dealloc(UPnPObject *self) -{ - freeUPNPDevlist(self->devlist); - FreeUPNPUrls(&self->urls); - free(self->multicastif); - free(self->minissdpdsocket); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyObject * -UPnP_discover(UPnPObject *self) -{ - struct UPNPDev * dev; - int i; - PyObject *res = NULL; - if(self->devlist) - { - freeUPNPDevlist(self->devlist); - self->devlist = 0; - } - Py_BEGIN_ALLOW_THREADS - self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/, - self->multicastif, - self->minissdpdsocket, - (int)self->localport, - 0/*ip v6*/, - 2/* TTL */, - 0/*error */); - Py_END_ALLOW_THREADS - /* Py_RETURN_NONE ??? */ - for(dev = self->devlist, i = 0; dev; dev = dev->pNext) - i++; - res = Py_BuildValue("i", i); - return res; -} - -static PyObject * -UPnP_selectigd(UPnPObject *self) -{ - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data, - self->lanaddr, sizeof(self->lanaddr)); -Py_END_ALLOW_THREADS - if(r) - { - return Py_BuildValue("s", self->urls.controlURL); - } - else - { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, "No UPnP device discovered"); - return NULL; - } -} - -static PyObject * -UPnP_totalbytesent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalbytereceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketsent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketreceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_statusinfo(UPnPObject *self) -{ - char status[64]; - char lastconnerror[64]; - unsigned int uptime = 0; - int r; - status[0] = '\0'; - lastconnerror[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype, - status, &uptime, lastconnerror); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror); -#else - return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_connectiontype(UPnPObject *self) -{ - char connectionType[64]; - int r; - connectionType[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetConnectionTypeInfo(self->urls.controlURL, - self->data.first.servicetype, - connectionType); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", connectionType); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_externalipaddress(UPnPObject *self) -{ - char externalIPAddress[40]; - int r; - externalIPAddress[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetExternalIPAddress(self->urls.controlURL, - self->data.first.servicetype, - externalIPAddress); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", externalIPAddress); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost, leaseDuration) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - unsigned int intLeaseDuration = 0; - char strLeaseDuration[12]; - int r; -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - if (!PyArg_ParseTuple(args, "HssHzz|I", &ePort, &proto, - &host, &iPort, &desc, &remoteHost, &intLeaseDuration)) -#else - if (!PyArg_ParseTuple(args, "HssHzz|i", &ePort, &proto, - &host, &iPort, &desc, &remoteHost, (int *)&intLeaseDuration)) -#endif - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - sprintf(strLeaseDuration, "%u", intLeaseDuration); - r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, strLeaseDuration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - Py_RETURN_TRUE; - } - else - { - // TODO: RAISE an Exception. See upnpcommands.h for errors codes. - // upnperrors.c - //Py_RETURN_FALSE; - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addanyportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - char reservedPort[6]; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration, reservedPort); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("i", atoi(reservedPort)); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - - -/* DeletePortMapping(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - int r; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, proto, remoteHost); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* DeletePortMappingRange(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args) -{ - char extPortStart[6]; - unsigned short ePortStart; - char extPortEnd[6]; - unsigned short ePortEnd; - const char * proto; - unsigned char manage; - char manageStr[6]; - int r; - if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPortStart, "%hu", ePortStart); - sprintf(extPortEnd, "%hu", ePortEnd); - sprintf(manageStr, "%hu", (unsigned short)manage); - r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype, - extPortStart, extPortEnd, proto, manageStr); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_getportmappingnumberofentries(UPnPObject *self) -{ - unsigned int n = 0; - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL, - self->data.first.servicetype, - &n); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", n); -#else - return Py_BuildValue("i", (int)n); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* GetSpecificPortMapping(ePort, proto, remoteHost='') - * proto = 'UDP' or 'TCP' */ -static PyObject * -UPnP_getspecificportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char desc[80]; - char enabled[4]; - char leaseDuration[16]; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; - extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0'; - desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - UPNP_GetSpecificPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - extPort, proto, remoteHost, - intClient, intPort, - desc, enabled, leaseDuration); -Py_END_ALLOW_THREADS - if(intClient[0]) - { - iPort = (unsigned short)atoi(intPort); - return Py_BuildValue("(s,H,s,O,i)", - intClient, iPort, desc, - PyBool_FromLong(atoi(enabled)), - atoi(leaseDuration)); - } - else - { - Py_RETURN_NONE; - } -} - -/* GetGenericPortMapping(index) */ -static PyObject * -UPnP_getgenericportmapping(UPnPObject *self, PyObject *args) -{ - int i, r; - char index[8]; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char extPort[6]; - unsigned short ePort; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; /* lease duration */ - unsigned int dur; - if(!PyArg_ParseTuple(args, "i", &i)) - return NULL; -Py_BEGIN_ALLOW_THREADS - snprintf(index, sizeof(index), "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, rHost, - duration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - ePort = (unsigned short)atoi(extPort); - iPort = (unsigned short)atoi(intPort); - dur = (unsigned int)strtoul(duration, 0, 0); -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(H,s,(s,H),s,s,s,I)", - ePort, protocol, intClient, iPort, - desc, enabled, rHost, dur); -#else - return Py_BuildValue("(i,s,(s,i),s,s,s,i)", - (int)ePort, protocol, intClient, (int)iPort, - desc, enabled, rHost, (int)dur); -#endif - } - else - { - Py_RETURN_NONE; - } -} - -/* miniupnpc.UPnP object Method Table */ -static PyMethodDef UPnP_methods[] = { - {"discover", (PyCFunction)UPnP_discover, METH_NOARGS, - "discover UPnP IGD devices on the network" - }, - {"selectigd", (PyCFunction)UPnP_selectigd, METH_NOARGS, - "select a valid UPnP IGD among discovered devices" - }, - {"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS, - "return the total number of bytes sent by UPnP IGD" - }, - {"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS, - "return the total number of bytes received by UPnP IGD" - }, - {"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS, - "return the total number of packets sent by UPnP IGD" - }, - {"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS, - "return the total number of packets received by UPnP IGD" - }, - {"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS, - "return status and uptime" - }, - {"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS, - "return IGD WAN connection type" - }, - {"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS, - "return external IP address" - }, - {"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS, - "add a port mapping" - }, - {"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS, - "add a port mapping, IGD to select alternative if necessary" - }, - {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS, - "delete a port mapping" - }, - {"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS, - "delete a range of port mappings" - }, - {"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS, - "-- non standard --" - }, - {"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS, - "get details about a specific port mapping entry" - }, - {"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS, - "get all details about the port mapping at index" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject UPnPType = { - PyVarObject_HEAD_INIT(NULL, - 0) /*ob_size*/ - "miniupnpc.UPnP", /*tp_name*/ - sizeof(UPnPObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)UPnPObject_dealloc,/*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - "UPnP objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - UPnP_methods, /* tp_methods */ - UPnP_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)UPnP_init, /* tp_init */ - 0, /* tp_alloc */ -#ifndef _WIN32 - PyType_GenericNew,/*UPnP_new,*/ /* tp_new */ -#else - 0, -#endif -}; - -/* module methods */ -static PyMethodDef miniupnpc_methods[] = { - {NULL} /* Sentinel */ -}; - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "miniupnpc", /* m_name */ - "miniupnpc module.", /* m_doc */ - -1, /* m_size */ - miniupnpc_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; -#endif - -#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ -#define PyMODINIT_FUNC void -#endif - -PyMODINIT_FUNC -#if PY_MAJOR_VERSION >= 3 -PyInit_miniupnpc(void) -#else -initminiupnpc(void) -#endif -{ - PyObject* m; - -#ifdef _WIN32 - /* initialize Winsock. */ - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if (nResult != 0) - { - /* error code could be WSASYSNOTREADY WSASYSNOTREADY - * WSASYSNOTREADY WSASYSNOTREADY WSASYSNOTREADY */ -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - } - - UPnPType.tp_new = PyType_GenericNew; -#endif - if (PyType_Ready(&UPnPType) < 0) -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("miniupnpc", miniupnpc_methods, - "miniupnpc module."); -#endif - - Py_INCREF(&UPnPType); - PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType); - -#if PY_MAJOR_VERSION >= 3 - return m; -#endif -} - diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h b/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h index a718cc7bbf..7b3d04074a 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h @@ -4,7 +4,7 @@ #include "core/version.h" #define OS_STRING VERSION_NAME "/1.0" -#define MINIUPNPC_VERSION_STRING "2.1" +#define MINIUPNPC_VERSION_STRING "2.2.2" #if 0 /* according to "UPnP Device Architecture 1.0" */ diff --git a/thirdparty/miniupnpc/miniupnpc/miniwget.c b/thirdparty/miniupnpc/miniupnpc/miniwget.c index 5c135f4efd..d5b7970632 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniwget.c +++ b/thirdparty/miniupnpc/miniupnpc/miniwget.c @@ -1,8 +1,8 @@ -/* $Id: miniwget.c,v 1.78 2018/03/13 23:22:18 nanard Exp $ */ +/* $Id: miniwget.c,v 1.82 2020/05/29 21:14:22 nanard Exp $ */ /* Project : miniupnp - * Website : http://miniupnp.free.fr/ + * Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas Bernard - * Copyright (c) 2005-2018 Thomas Bernard + * Copyright (c) 2005-2020 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -15,7 +15,7 @@ #include #include #define MAXHOSTNAMELEN 64 -#define snprintf _snprintf +#include "win32_snprintf.h" #define socklen_t int #ifndef strncasecmp #if defined(_MSC_VER) && (_MSC_VER >= 1400) @@ -176,11 +176,14 @@ getHTTPResponse(SOCKET s, int * size, int * status_code) /* Status line * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ int sp; - for(sp = 0; sp < i; sp++) + for(sp = 0; sp < i - 1; sp++) if(header_buf[sp] == ' ') { if(*status_code < 0) - *status_code = atoi(header_buf + sp + 1); + { + if (header_buf[sp+1] >= '1' && header_buf[sp+1] <= '9') + *status_code = atoi(header_buf + sp + 1); + } else { #ifdef DEBUG diff --git a/thirdparty/miniupnpc/miniupnpc/portlistingparse.c b/thirdparty/miniupnpc/miniupnpc/portlistingparse.c index 18d967b877..162cf8b7ec 100644 --- a/thirdparty/miniupnpc/miniupnpc/portlistingparse.c +++ b/thirdparty/miniupnpc/miniupnpc/portlistingparse.c @@ -15,7 +15,7 @@ #if defined(__HAIKU__) /* rename our private function because Haiku already defines a atoui() function */ #define atoui atoui2 -#endif +#endif /* list of the elements */ static const struct { diff --git a/thirdparty/miniupnpc/miniupnpc/receivedata.c b/thirdparty/miniupnpc/miniupnpc/receivedata.c index 7b9cc5b778..7f187f6e56 100644 --- a/thirdparty/miniupnpc/miniupnpc/receivedata.c +++ b/thirdparty/miniupnpc/miniupnpc/receivedata.c @@ -1,8 +1,8 @@ -/* $Id: receivedata.c,v 1.7 2015/11/09 21:51:41 nanard Exp $ */ +/* $Id: receivedata.c,v 1.10 2021/03/02 23:33:07 nanard Exp $ */ /* Project : miniupnp * Website : http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2011-2014 Thomas Bernard + * Copyright (c) 2011-2021 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -92,7 +92,13 @@ receivedata(SOCKET socket, #endif /* DEBUG */ if(scope_id) *scope_id = src_addr6->sin6_scope_id; + } else { + if(scope_id) + *scope_id = 0; } +#else /* MINIUPNPC_GET_SRC_ADDR */ + if(scope_id) + *scope_id = 0; #endif /* MINIUPNPC_GET_SRC_ADDR */ return n; } diff --git a/thirdparty/miniupnpc/miniupnpc/upnpc.c b/thirdparty/miniupnpc/miniupnpc/upnpc.c deleted file mode 100644 index cb7f18b5f6..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/upnpc.c +++ /dev/null @@ -1,864 +0,0 @@ -/* $Id: upnpc.c,v 1.119 2018/03/13 23:34:46 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2020 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#include -#include -#ifdef _WIN32 -#include -#define snprintf _snprintf -#else -/* for IPPROTO_TCP / IPPROTO_UDP */ -#include -#endif -#include -#include "miniwget.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "portlistingparse.h" -#include "upnperrors.h" -#include "miniupnpcstrings.h" - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - static const char proto_udp[4] = { 'U', 'D', 'P', 0}; - int i, b; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); - if(b) - return proto_tcp; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); - if(b) - return proto_udp; - return 0; -} - -/* is_int() checks if parameter is an integer or not - * 1 for integer - * 0 for not an integer */ -int is_int(char const* s) -{ - if(s == NULL) - return 0; - while(*s) { - /* #define isdigit(c) ((c) >= '0' && (c) <= '9') */ - if(!isdigit(*s)) - return 0; - s++; - } - return 1; -} - -static void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - char externalIPAddress[40]; - char connectionType[64]; - char status[64]; - char lastconnerr[64]; - unsigned int uptime = 0; - unsigned int brUp, brDown; - time_t timenow, timestarted; - int r; - if(UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType) != UPNPCOMMAND_SUCCESS) - printf("GetConnectionTypeInfo failed.\n"); - else - printf("Connection Type : %s\n", connectionType); - if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) - printf("GetStatusInfo failed.\n"); - else - printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); - if(uptime > 0) { - timenow = time(NULL); - timestarted = timenow - uptime; - printf(" Time started : %s", ctime(×tarted)); - } - if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { - printf("GetLinkLayerMaxBitRates failed.\n"); - } else { - printf("MaxBitRateDown : %u bps", brDown); - if(brDown >= 1000000) { - printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); - } else if(brDown >= 1000) { - printf(" (%u Kbps)", brDown / 1000); - } - printf(" MaxBitRateUp %u bps", brUp); - if(brUp >= 1000000) { - printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); - } else if(brUp >= 1000) { - printf(" (%u Kbps)", brUp / 1000); - } - printf("\n"); - } - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) { - printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); - } else { - printf("ExternalIPAddress = %s\n", externalIPAddress); - } -} - -static void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -static void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - char index[6]; - char intClient[40]; - char intPort[6]; - char extPort[6]; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; - /*unsigned int num=0; - UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); - printf("PortMappingNumberOfEntries : %u\n", num);*/ - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - do { - snprintf(index, 6, "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, - data->first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" - " desc='%s' rHost='%s'\n", - i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); - */ - printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", - i, protocol, extPort, intClient, intPort, - desc, rHost, duration); - else - printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); - i++; - } while(r==0); -} - -static void NewListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - struct PortMappingParserData pdata; - struct PortMapping * pm; - - memset(&pdata, 0, sizeof(struct PortMappingParserData)); - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "TCP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "UDP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } -} - -/* Test function - * 1 - get connection type - * 2 - get extenal ip address - * 3 - Add port mapping - * 4 - get this port mapping from the IGD */ -static int SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto, - const char * leaseDuration, - const char * remoteHost, - const char * description, - int addAny) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - char reservedPort[6]; - char duration[16]; - int r; - - if(!iaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "invalid protocol\n"); - return -1; - } - - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetExternalIPAddress failed.\n"); - else - printf("ExternalIPAddress = %s\n", externalIPAddress); - - if (addAny) { - r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, remoteHost, leaseDuration, reservedPort); - if(r==UPNPCOMMAND_SUCCESS) - eport = reservedPort; - else - printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - } else { - r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, remoteHost, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - return -2; - } - } - - r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->first.servicetype, - eport, proto, remoteHost, - intClient, intPort, NULL/*desc*/, - NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", - r, strupnperror(r)); - return -2; - } else { - printf("InternalIP:Port = %s:%s\n", intClient, intPort); - printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", - externalIPAddress, eport, proto, intClient, intPort, duration); - } - return 0; -} - -static int -RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto, - const char * remoteHost) -{ - int r; - if(!proto || !eport) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMapping() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMapping() returned : %d\n", r); - } - return 0; -} - -static int -RemoveRedirectRange(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * ePortStart, char const * ePortEnd, - const char * proto, const char * manage) -{ - int r; - - if (!manage) - manage = "0"; - - if(!proto || !ePortStart || !ePortEnd) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMappingRange() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMappingRange() returned : %d\n", r); - } - return 0; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - int firewallEnabled = 0, inboundPinholeAllowed = 0; - - UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed); - printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed); - printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No"); - - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -/* Test function - * 1 - Add pinhole - * 2 - Check if pinhole is working from the IGD side */ -static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto, const char * lease_time) -{ - char uniqueID[8]; - /*int isWorking = 0;*/ - int r; - char proto_tmp[8]; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - if(atoi(proto) == 0) - { - const char * protocol; - protocol = protofix(proto); - if(protocol && (strcmp("TCP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP); - proto = proto_tmp; - } - else if(protocol && (strcmp("UDP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP); - proto = proto_tmp; - } - else - { - fprintf(stderr, "invalid protocol\n"); - return; - } - } - r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID); - if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - remoteaddr, eport, intaddr, iport, r, strupnperror(r)); - else - { - printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", - remoteaddr, eport, intaddr, iport, uniqueID); - /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/ - } -} - -/* Test function - * 1 - Check if pinhole is working from the IGD side - * 2 - Update pinhole */ -static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, - const char * uniqueID, const char * lease_time) -{ - int isWorking = 0; - int r; - - if(!uniqueID || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) - { - r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); - printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); - if(r!=UPNPCOMMAND_SUCCESS) - printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); - } -} - -/* Test function - * Get pinhole timeout - */ -static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto) -{ - int timeout = 0; - int r; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - - r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); - else - printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout); -} - -static void -GetPinholePackets(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, pinholePackets = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets); -} - -static void -CheckPinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, isWorking = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); -} - -static void -RemovePinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID); - printf("UPNP_DeletePinhole() returned : %d\n", r); -} - - -/* sample upnp client program */ -int main(int argc, char ** argv) -{ - char command = 0; - char ** commandargv = 0; - int commandargc = 0; - struct UPNPDev * devlist = 0; - char lanaddr[64] = "unset"; /* my ip address on the LAN */ - int i; - const char * rootdescurl = 0; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int localport = UPNP_LOCAL_PORT_ANY; - int retcode = 0; - int error = 0; - int ipv6 = 0; - unsigned char ttl = 2; /* defaulting to 2 */ - const char * description = 0; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2020 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n" - "for more information.\n"); - /* command line processing */ - for(i=1; i65535 || - (localport >1 && localport < 1024)) - { - fprintf(stderr, "Invalid localport '%s'\n", argv[i]); - localport = UPNP_LOCAL_PORT_ANY; - break; - } - } - else if(argv[i][1] == 'p') - minissdpdpath = argv[++i]; - else if(argv[i][1] == '6') - ipv6 = 1; - else if(argv[i][1] == 'e') - description = argv[++i]; - else if(argv[i][1] == 't') - ttl = (unsigned char)atoi(argv[++i]); - else - { - command = argv[i][1]; - i++; - commandargv = argv + i; - commandargc = argc - i; - break; - } - } - else - { - fprintf(stderr, "option '%s' invalid\n", argv[i]); - } - } - - if(!command - || (command == 'a' && commandargc<4) - || (command == 'd' && argc<2) - || (command == 'r' && argc<2) - || (command == 'A' && commandargc<6) - || (command == 'U' && commandargc<2) - || (command == 'D' && commandargc<1)) - { - fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration] [remote host]\n\t\tAdd port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -d external_port protocol [remote host]\n\t\tDelete port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); - fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); - fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration] [remote host]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); - fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]); - fprintf(stderr, "\nprotocol is UDP or TCP\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -e description : set description for port mapping.\n"); - fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n"); - fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); - fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n"); - fprintf(stderr, " -z localport : SSDP packets local (source) port (1024-65535).\n"); - fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); - fprintf(stderr, " -t ttl : set multicast TTL. Default value is 2.\n"); - return 1; - } - - if( rootdescurl - || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, - localport, ipv6, ttl, &error))) - { - struct UPNPDev * device; - struct UPNPUrls urls; - struct IGDdatas data; - if(devlist) - { - printf("List of UPNP devices found on the network :\n"); - for(device = devlist; device; device = device->pNext) - { - printf(" desc: %s\n st: %s\n\n", - device->descURL, device->st); - } - } - else if(!rootdescurl) - { - printf("upnpDiscover() error code=%d\n", error); - } - i = 1; - if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) - || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) - { - switch(i) { - case 1: - printf("Found valid IGD : %s\n", urls.controlURL); - break; - case 2: - printf("Found a (not connected?) IGD : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - case 3: - printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - default: - printf("Found device (igd ?) : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - } - printf("Local LAN ip address : %s\n", lanaddr); - #if 0 - printf("getting \"%s\"\n", urls.ipcondescURL); - descXML = miniwget(urls.ipcondescURL, &descXMLsize); - if(descXML) - { - /*fwrite(descXML, 1, descXMLsize, stdout);*/ - free(descXML); descXML = NULL; - } - #endif - - switch(command) - { - case 'l': - DisplayInfos(&urls, &data); - ListRedirections(&urls, &data); - break; - case 'L': - NewListRedirections(&urls, &data); - break; - case 'a': - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)&is_int(commandargv[4])?commandargv[4]:"0", - (commandargc > 4)&!is_int(commandargv[4])?commandargv[4]:(commandargc > 5)?commandargv[5]:NULL, - description, 0) < 0) - retcode = 2; - break; - case 'd': - if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL) < 0) - retcode = 2; - break; - case 'n': /* aNy */ - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)&is_int(commandargv[4])?commandargv[4]:"0", - (commandargc > 4)&!is_int(commandargv[4])?commandargv[4]:(commandargc > 5)?commandargv[5]:NULL, - description, 1) < 0) - retcode = 2; - break; - case 'N': - if (commandargc < 3) - fprintf(stderr, "too few arguments\n"); - - if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL) < 0) - retcode = 2; - break; - case 's': - GetConnectionStatus(&urls, &data); - break; - case 'r': - i = 0; - while(i */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i+1], commandargv[i+2], "0", NULL, - description, 0) < 0) - retcode = 2; - i+=3; /* 3 parameters parsed */ - } else { - /* 2nd parameter not an integer : */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i], commandargv[i+1], "0", NULL, - description, 0) < 0) - retcode = 2; - i+=2; /* 2 parameters parsed */ - } - } - break; - case 'A': - SetPinholeAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4], commandargv[5]); - break; - case 'U': - GetPinholeAndUpdate(&urls, &data, - commandargv[0], commandargv[1]); - break; - case 'C': - for(i=0; i= 199901L + /* C99 flexible array member */ + char buffer[]; +#elif defined(__GNUC__) + char buffer[0]; +#else + /* Fallback to a hack */ + char buffer[1]; +#endif }; /* freeUPNPDevlist() diff --git a/thirdparty/miniupnpc/miniupnpc/upnperrors.c b/thirdparty/miniupnpc/miniupnpc/upnperrors.c deleted file mode 100644 index 4496e8622c..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/upnperrors.c +++ /dev/null @@ -1,112 +0,0 @@ -/* $Id: upnperrors.c,v 1.10 2019/08/24 08:49:53 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2007-2019 Thomas Bernard - * All Right reserved. - * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#include "upnperrors.h" -#include "upnpcommands.h" -#include "miniupnpc.h" - -const char * strupnperror(int err) -{ - const char * s = NULL; - switch(err) { - case UPNPCOMMAND_SUCCESS: - s = "Success"; - break; - case UPNPCOMMAND_UNKNOWN_ERROR: - s = "Miniupnpc Unknown Error"; - break; - case UPNPCOMMAND_INVALID_ARGS: - s = "Miniupnpc Invalid Arguments"; - break; - case UPNPCOMMAND_INVALID_RESPONSE: - s = "Miniupnpc Invalid response"; - break; - case UPNPCOMMAND_HTTP_ERROR: - s = "Miniupnpc HTTP error"; - break; - case UPNPDISCOVER_SOCKET_ERROR: - s = "Miniupnpc Socket error"; - break; - case UPNPDISCOVER_MEMORY_ERROR: - case UPNPCOMMAND_MEM_ALLOC_ERROR: - s = "Miniupnpc Memory allocation error"; - break; - case 401: - s = "Invalid Action"; - break; - case 402: - s = "Invalid Args"; - break; - case 501: - s = "Action Failed"; - break; - case 606: - s = "Action not authorized"; - break; - case 701: - s = "PinholeSpaceExhausted"; - break; - case 702: - s = "FirewallDisabled"; - break; - case 703: - s = "InboundPinholeNotAllowed"; - break; - case 704: - s = "NoSuchEntry"; - break; - case 705: - s = "ProtocolNotSupported"; - break; - case 706: - s = "InternalPortWildcardingNotAllowed"; - break; - case 707: - s = "ProtocolWildcardingNotAllowed"; - break; - case 708: - s = "InvalidLayer2Address"; - break; - case 709: - s = "NoPacketSent"; - break; - case 713: - s = "SpecifiedArrayIndexInvalid"; - break; - case 714: - s = "NoSuchEntryInArray"; - break; - case 715: - s = "WildCardNotPermittedInSrcIP"; - break; - case 716: - s = "WildCardNotPermittedInExtPort"; - break; - case 718: - s = "ConflictInMappingEntry"; - break; - case 724: - s = "SamePortValuesRequired"; - break; - case 725: - s = "OnlyPermanentLeasesSupported"; - break; - case 726: - s = "RemoteHostOnlySupportsWildcard"; - break; - case 727: - s = "ExternalPortOnlySupportsWildcard"; - break; - default: - s = "UnknownError"; - break; - } - return s; -} diff --git a/thirdparty/miniupnpc/miniupnpc/upnperrors.h b/thirdparty/miniupnpc/miniupnpc/upnperrors.h deleted file mode 100644 index 8499d9a1c9..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/upnperrors.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */ -/* (c) 2007-2015 Thomas Bernard - * All rights reserved. - * MiniUPnP Project. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#ifndef UPNPERRORS_H_INCLUDED -#define UPNPERRORS_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* strupnperror() - * Return a string description of the UPnP error code - * or NULL for undefinded errors */ -MINIUPNP_LIBSPEC const char * strupnperror(int err); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/miniupnpc/miniupnpc/win32_snprintf.h b/thirdparty/miniupnpc/miniupnpc/win32_snprintf.h new file mode 100644 index 0000000000..1fc284ecff --- /dev/null +++ b/thirdparty/miniupnpc/miniupnpc/win32_snprintf.h @@ -0,0 +1,71 @@ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * MiniUPnP project + * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ + * (c) 2020 Pali Rohár + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ + +#ifndef WIN32_SNPRINTF_H +#define WIN32_SNPRINTF_H + +#ifdef _WIN32 + +#include + +/* snprintf is supported by: + * - Visual Studio 2015 or new + * - mingw32 with iso c ext + * - mingw-w64 with ansi stdio + * - mingw-w64 6.0.0 or new with ucrt + * - mingw-w64 8.0.0 or new with iso c ext + */ +#if ( \ + (defined(_MSC_VER) && _MSC_VER < 1900) /* Visual Studio older than 2015 */ || \ + (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__NO_ISOCEXT)) /* mingw32 without iso c ext */ || \ + (defined(__MINGW64_VERSION_MAJOR) && /* mingw-w64 not ... */ !( \ + (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0)) /* ... with ansi stdio */ || \ + (__MINGW64_VERSION_MAJOR >= 6 && defined(_UCRT)) /* ... at least 6.0.0 with ucrt */ || \ + (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT)) /* ... at least 8.0.0 with iso c ext */ || \ + 0) || \ +0) + +/* _scprintf is supported by: + * - Visual Studio 2002 or new + * - msvcr70.dll or new + * - msvcrt.dll on Windows XP or new + */ +#if ( \ + (defined(_MSC_VER) && _MSC_VER < 1300) /* Visual Studio older than 2002 */ || \ + (defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x700) /* msvcrt older than 7.0 */ || \ +0) +#define CHECK_SCPRINTF 0 +#define IF_SCPRINTF(expr) 0 +#define ELSE_SCPRINTF(expr) expr +#else +#define CHECK_SCPRINTF 1 +#define IF_SCPRINTF(expr) expr +#define ELSE_SCPRINTF(expr) 0 +#endif + +/* Emulation of snprintf for win32 */ +#define snprintf(buf, size, fmt, ...) ( \ + (((size) != 0 && (buf) != NULL) ? ( /* _snprintf does not work with NULL buffer */ \ + _snprintf((buf), (size), (fmt), __VA_ARGS__), /* _snprintf returns -1 on overflow, so ignore its value */ \ + (((char *)buf)[(size_t)(size)-1] = 0), /* _snprintf does not fill nul byte on overflow */ \ + 0) : 0), \ + (CHECK_SCPRINTF ? IF_SCPRINTF( \ + _scprintf((fmt), __VA_ARGS__) /* calculate return value for snprintf via _scprintf */ \ + ) : ELSE_SCPRINTF( \ + ((size) != 0 && (buf) != NULL) ? \ + strlen((buf)) /* return just length of buffer */ \ + : \ + 1 /* no buffer, impossible to calculate, return just non-zero number */ \ + ) \ + ) \ +) + +#endif + +#endif /* _WIN32 */ + +#endif /* WIN32_SNPRINTF_H */