mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
miniupnpc: Update to version 2.2.2
This commit is contained in:
parent
245cfcaba6
commit
69486b1059
@ -269,7 +269,7 @@ License: CC0-1.0
|
|||||||
|
|
||||||
Files: ./thirdparty/miniupnpc/
|
Files: ./thirdparty/miniupnpc/
|
||||||
Comment: MiniUPnPc
|
Comment: MiniUPnPc
|
||||||
Copyright: 2005-2019, Thomas Bernard
|
Copyright: 2005-2021, Thomas Bernard
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
|
||||||
Files: ./thirdparty/minizip/
|
Files: ./thirdparty/minizip/
|
||||||
|
@ -12,18 +12,19 @@ thirdparty_obj = []
|
|||||||
if env["builtin_miniupnpc"]:
|
if env["builtin_miniupnpc"]:
|
||||||
thirdparty_dir = "#thirdparty/miniupnpc/"
|
thirdparty_dir = "#thirdparty/miniupnpc/"
|
||||||
thirdparty_sources = [
|
thirdparty_sources = [
|
||||||
"miniupnpc.c",
|
|
||||||
"upnpcommands.c",
|
|
||||||
"miniwget.c",
|
|
||||||
"upnpdev.c",
|
|
||||||
"igd_desc_parse.c",
|
"igd_desc_parse.c",
|
||||||
"minissdpc.c",
|
"miniupnpc.c",
|
||||||
"minisoap.c",
|
|
||||||
"minixml.c",
|
"minixml.c",
|
||||||
"connecthostport.c",
|
"minisoap.c",
|
||||||
"receivedata.c",
|
"minissdpc.c",
|
||||||
"portlistingparse.c",
|
"miniwget.c",
|
||||||
|
"upnpcommands.c",
|
||||||
|
"upnpdev.c",
|
||||||
"upnpreplyparse.c",
|
"upnpreplyparse.c",
|
||||||
|
"connecthostport.c",
|
||||||
|
"portlistingparse.c",
|
||||||
|
"receivedata.c",
|
||||||
|
"addr_is_reserved.c",
|
||||||
]
|
]
|
||||||
thirdparty_sources = [thirdparty_dir + "miniupnpc/" + file for file in thirdparty_sources]
|
thirdparty_sources = [thirdparty_dir + "miniupnpc/" + file for file in thirdparty_sources]
|
||||||
|
|
||||||
|
13
thirdparty/README.md
vendored
13
thirdparty/README.md
vendored
@ -355,17 +355,20 @@ Files extracted from upstream repository:
|
|||||||
|
|
||||||
## miniupnpc
|
## miniupnpc
|
||||||
|
|
||||||
- Upstream: https://github.com/miniupnp/miniupnp/tree/master/miniupnpc
|
- Upstream: https://github.com/miniupnp/miniupnp
|
||||||
- Version: git (44366328661826603982d1e0d7ebb4062c5f2bfc, 2020)
|
- Version: 2.2.2 (81029a860baf1f727903e5b85307903b3f40cbc8, 2021)
|
||||||
- License: BSD-3-Clause
|
- License: BSD-3-Clause
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
||||||
- All `*.c` and `*.h` files from `miniupnpc` to `thirdparty/miniupnpc/miniupnpc`
|
- 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
|
The only modified file is `miniupnpcstrings.h`, which was created for Godot
|
||||||
(it is usually autogenerated by cmake).
|
(it is usually autogenerated by cmake). Bump the version number for miniupnpc in that
|
||||||
|
file when upgrading.
|
||||||
|
|
||||||
|
|
||||||
## minizip
|
## minizip
|
||||||
|
5
thirdparty/miniupnpc/LICENSE
vendored
5
thirdparty/miniupnpc/LICENSE
vendored
@ -1,5 +1,5 @@
|
|||||||
MiniUPnP Project
|
MiniUPnPc
|
||||||
Copyright (c) 2005-2019, Thomas BERNARD
|
Copyright (c) 2005-2020, Thomas BERNARD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
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)
|
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
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
79
thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c
vendored
Normal file
79
thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c
vendored
Normal file
@ -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 <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
#include <stdint.h>
|
||||||
|
#else /* !defined(_MSC_VER) */
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
#endif /* !defined(_MSC_VER) */
|
||||||
|
#else /* _WIN32 */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#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;
|
||||||
|
}
|
14
thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h
vendored
Normal file
14
thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h
vendored
Normal file
@ -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 */
|
@ -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
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* Project : miniupnp
|
* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
@ -19,7 +19,7 @@
|
|||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define MAXHOSTNAMELEN 64
|
#define MAXHOSTNAMELEN 64
|
||||||
#define snprintf _snprintf
|
#include "win32_snprintf.h"
|
||||||
#define herror
|
#define herror
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
#else /* #ifdef _WIN32 */
|
#else /* #ifdef _WIN32 */
|
||||||
|
197
thirdparty/miniupnpc/miniupnpc/listdevices.c
vendored
197
thirdparty/miniupnpc/miniupnpc/listdevices.c
vendored
@ -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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#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 <device1> <device2> ...]\n", argv[0]);
|
|
||||||
printf("options :\n");
|
|
||||||
printf(" -6 : use IPv6\n");
|
|
||||||
printf(" -m address/ifname : network interface to use for multicast\n");
|
|
||||||
printf(" -d <device string> : search only for this type of device\n");
|
|
||||||
printf(" -l <device1> <device2> ... : 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;
|
|
||||||
}
|
|
||||||
|
|
6
thirdparty/miniupnpc/miniupnpc/minisoap.c
vendored
6
thirdparty/miniupnpc/miniupnpc/minisoap.c
vendored
@ -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
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* Project : miniupnp
|
* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution.
|
* LICENCE file provided in this distribution.
|
||||||
*
|
*
|
||||||
@ -13,7 +13,7 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#define snprintf _snprintf
|
#include "win32_snprintf.h"
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
232
thirdparty/miniupnpc/miniupnpc/minissdpc.c
vendored
232
thirdparty/miniupnpc/miniupnpc/minissdpc.c
vendored
@ -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
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* Project : miniupnp
|
* Project : miniupnp
|
||||||
* Web : http://miniupnp.free.fr/
|
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
* Author : Thomas BERNARD
|
* 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
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENCE file. */
|
* provided LICENCE file. */
|
||||||
/*#include <syslog.h>*/
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#if defined (__NetBSD__)
|
#if defined (__NetBSD__)
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#define snprintf _snprintf
|
#include "win32_snprintf.h"
|
||||||
#if !defined(_MSC_VER)
|
#if !defined(_MSC_VER)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else /* !defined(_MSC_VER) */
|
#else /* !defined(_MSC_VER) */
|
||||||
@ -33,6 +33,12 @@ typedef unsigned short uint16_t;
|
|||||||
#define strncasecmp memicmp
|
#define strncasecmp memicmp
|
||||||
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
#endif /* #ifndef strncasecmp */
|
#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 */
|
#endif /* _WIN32 */
|
||||||
#if defined(__amigaos__) || defined(__amigaos4__)
|
#if defined(__amigaos__) || defined(__amigaos4__)
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -66,7 +72,7 @@ struct sockaddr_un {
|
|||||||
#define HAS_IP_MREQN
|
#define HAS_IP_MREQN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAS_IP_MREQN) && !defined(_WIN32)
|
#ifndef _WIN32
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#if defined(__sun) || defined(__HAIKU__)
|
#if defined(__sun) || defined(__HAIKU__)
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
@ -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 */
|
/* port upnp discover : SSDP protocol */
|
||||||
#define SSDP_PORT 1900
|
#define SSDP_PORT 1900
|
||||||
#define XSTR(s) STR(s)
|
#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) */
|
* in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
|
||||||
if(!ipv6) {
|
if(!ipv6) {
|
||||||
DWORD ifbestidx;
|
DWORD ifbestidx;
|
||||||
SOCKADDR_IN destAddr;
|
if (GetBestInterface(inet_addr("223.255.255.255"), &ifbestidx) == NO_ERROR) {
|
||||||
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) {
|
|
||||||
DWORD dwRetVal = NO_ERROR;
|
DWORD dwRetVal = NO_ERROR;
|
||||||
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
|
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
|
||||||
ULONG outBufLen = 15360;
|
ULONG outBufLen = 15360;
|
||||||
@ -672,6 +703,13 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
|
|||||||
* MS Windows Vista and MS Windows Server 2008.
|
* MS Windows Vista and MS Windows Server 2008.
|
||||||
* http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
|
* http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
|
||||||
unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
|
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)
|
if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0)
|
||||||
{
|
{
|
||||||
PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF");
|
PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF");
|
||||||
@ -683,10 +721,17 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
struct in_addr mc_if;
|
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);
|
InetPtonA(AF_INET, multicastif, &mc_if);
|
||||||
#else
|
#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
|
#endif
|
||||||
if(mc_if.s_addr != INADDR_NONE)
|
if(mc_if.s_addr != INADDR_NONE)
|
||||||
{
|
{
|
||||||
@ -696,16 +741,11 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
|
|||||||
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
|
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAS_IP_MREQN
|
|
||||||
/* was not an ip address, try with an interface name */
|
/* 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 */
|
struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */
|
||||||
memset(&reqn, 0, sizeof(struct ip_mreqn));
|
#endif
|
||||||
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)
|
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int ifrlen = sizeof(ifr);
|
int ifrlen = sizeof(ifr);
|
||||||
strncpy(ifr.ifr_name, multicastif, IFNAMSIZ);
|
strncpy(ifr.ifr_name, multicastif, IFNAMSIZ);
|
||||||
@ -713,12 +753,30 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
|
|||||||
if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0)
|
if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0)
|
||||||
{
|
{
|
||||||
PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)");
|
PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)");
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
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)
|
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
|
||||||
{
|
{
|
||||||
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
|
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Setting of multicast interface not supported with interface name.\n");
|
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
|
/* Waiting for SSDP REPLY packet to M-SEARCH
|
||||||
* if searchalltypes is set, enter the loop only
|
* if searchalltypes is set, enter the loop only
|
||||||
* when the last deviceType is reached */
|
* when the last deviceType is reached */
|
||||||
if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do {
|
if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) {
|
||||||
n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
|
struct timeval start = {0, 0}, current = {0, 0};
|
||||||
if (n < 0) {
|
upnp_gettimeofday(&start);
|
||||||
/* error */
|
do {
|
||||||
if(error)
|
n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
|
||||||
*error = MINISSDPC_SOCKET_ERROR;
|
if (n < 0) {
|
||||||
goto error;
|
/* 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(error)
|
if(error)
|
||||||
*error = MINISSDPC_SUCCESS;
|
*error = MINISSDPC_SOCKET_ERROR;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
} else if (n == 0) {
|
||||||
} else {
|
/* no data or Time Out */
|
||||||
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
|
#ifdef DEBUG
|
||||||
printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n",
|
printf("NODATA or TIMEOUT\n");
|
||||||
stsize, st, usnsize, (usn?usn:""), urlsize, descURL);
|
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
for(tmp=devlist; tmp; tmp = tmp->pNext) {
|
if (devlist && !searchalltypes) {
|
||||||
if(strncmp(tmp->descURL, descURL, urlsize) == 0 &&
|
/* found some devices, stop now*/
|
||||||
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(error)
|
if(error)
|
||||||
*error = MINISSDPC_MEMORY_ERROR;
|
*error = MINISSDPC_SUCCESS;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
tmp->pNext = devlist;
|
} else {
|
||||||
tmp->descURL = tmp->buffer;
|
const char * descURL=NULL;
|
||||||
tmp->st = tmp->buffer + 1 + urlsize;
|
int urlsize=0;
|
||||||
tmp->usn = tmp->st + 1 + stsize;
|
const char * st=NULL;
|
||||||
memcpy(tmp->buffer, descURL, urlsize);
|
int stsize=0;
|
||||||
tmp->buffer[urlsize] = '\0';
|
const char * usn=NULL;
|
||||||
memcpy(tmp->st, st, stsize);
|
int usnsize=0;
|
||||||
tmp->buffer[urlsize+1+stsize] = '\0';
|
parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize);
|
||||||
if(usn != NULL)
|
if(st&&descURL) {
|
||||||
memcpy(tmp->usn, usn, usnsize);
|
#ifdef DEBUG
|
||||||
tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0';
|
printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n",
|
||||||
tmp->scope_id = scope_id;
|
stsize, st, usnsize, (usn?usn:""), urlsize, descURL);
|
||||||
devlist = tmp;
|
#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) {
|
if(ipv6) {
|
||||||
/* switch linklocal flag */
|
/* switch linklocal flag */
|
||||||
if(linklocal) {
|
if(linklocal) {
|
||||||
@ -923,4 +992,3 @@ error:
|
|||||||
closesocket(sudp);
|
closesocket(sudp);
|
||||||
return devlist;
|
return devlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
thirdparty/miniupnpc/miniupnpc/miniupnpc.c
vendored
35
thirdparty/miniupnpc/miniupnpc/miniupnpc.c
vendored
@ -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
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* Project : miniupnp
|
* Project : miniupnp
|
||||||
* Web : http://miniupnp.free.fr/
|
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
* Author : Thomas BERNARD
|
* 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
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENSE file. */
|
* provided LICENSE file. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#define snprintf _snprintf
|
#include "win32_snprintf.h"
|
||||||
#define strdup _strdup
|
#define strdup _strdup
|
||||||
#ifndef strncasecmp
|
#ifndef strncasecmp
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
@ -61,6 +61,7 @@
|
|||||||
#include "minixml.h"
|
#include "minixml.h"
|
||||||
#include "upnpcommands.h"
|
#include "upnpcommands.h"
|
||||||
#include "connecthostport.h"
|
#include "connecthostport.h"
|
||||||
|
#include "addr_is_reserved.h"
|
||||||
|
|
||||||
/* compare the beginning of a string with a constant string */
|
/* compare the beginning of a string with a constant string */
|
||||||
#define COMPARE(str, cstr) (0==strncmp(str, cstr, sizeof(cstr) - 1))
|
#define COMPARE(str, cstr) (0==strncmp(str, cstr, sizeof(cstr) - 1))
|
||||||
@ -73,24 +74,6 @@
|
|||||||
#define SERVICEPREFIX "u"
|
#define SERVICEPREFIX "u"
|
||||||
#define SERVICEPREFIX2 '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 */
|
/* root description parsing */
|
||||||
MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
|
MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
|
||||||
{
|
{
|
||||||
@ -337,6 +320,8 @@ upnpDiscoverDevices(const char * const deviceTypes[],
|
|||||||
return devlist;
|
return devlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
(void)minissdpdsock; /* unused */
|
||||||
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
|
||||||
/* direct discovery if minissdpd responses are not sufficient */
|
/* 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 */
|
/* checks that status is connected AND there is a external IP address assigned */
|
||||||
if(is_connected &&
|
if(is_connected &&
|
||||||
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
|
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
|
||||||
if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
|
if(!addr_is_reserved(extIpAddr))
|
||||||
&& (0 != strcmp(extIpAddr, "0.0.0.0")))
|
|
||||||
goto free_and_return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
FreeUPNPUrls(urls);
|
FreeUPNPUrls(urls);
|
||||||
@ -665,8 +649,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
|||||||
#endif
|
#endif
|
||||||
if(is_connected &&
|
if(is_connected &&
|
||||||
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
|
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
|
||||||
if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
|
if(!addr_is_reserved(extIpAddr))
|
||||||
&& (0 != strcmp(extIpAddr, "0.0.0.0")))
|
|
||||||
goto free_and_return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
FreeUPNPUrls(urls);
|
FreeUPNPUrls(urls);
|
||||||
|
6
thirdparty/miniupnpc/miniupnpc/miniupnpc.h
vendored
6
thirdparty/miniupnpc/miniupnpc/miniupnpc.h
vendored
@ -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
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* Project: miniupnp
|
* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2005-2018 Thomas Bernard
|
* Copyright (c) 2005-2021 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef MINIUPNPC_H_INCLUDED
|
#ifndef MINIUPNPC_H_INCLUDED
|
||||||
@ -20,7 +20,7 @@
|
|||||||
#define UPNPDISCOVER_MEMORY_ERROR (-102)
|
#define UPNPDISCOVER_MEMORY_ERROR (-102)
|
||||||
|
|
||||||
/* versions : */
|
/* versions : */
|
||||||
#define MINIUPNPC_VERSION "2.1"
|
#define MINIUPNPC_VERSION "2.2.2"
|
||||||
#define MINIUPNPC_API_VERSION 17
|
#define MINIUPNPC_API_VERSION 17
|
||||||
|
|
||||||
/* Source port:
|
/* Source port:
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#ifndef MINIUPNPC_SOCKETDEF_H_INCLUDED
|
#ifndef MINIUPNPC_SOCKETDEF_H_INCLUDED
|
||||||
#define MINIUPNPC_SOCKETDEF_H_INCLUDED
|
#define MINIUPNPC_SOCKETDEF_H_INCLUDED
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
|
|
||||||
#define ISINVALID(s) (INVALID_SOCKET==(s))
|
#define ISINVALID(s) (INVALID_SOCKET==(s))
|
||||||
|
|
||||||
|
721
thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c
vendored
721
thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c
vendored
@ -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 <Python.h>
|
|
||||||
#define MINIUPNP_STATICLIB
|
|
||||||
#include "structmember.h"
|
|
||||||
#include "miniupnpc.h"
|
|
||||||
#include "upnpcommands.h"
|
|
||||||
#include "upnperrors.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#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
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
|||||||
#include "core/version.h"
|
#include "core/version.h"
|
||||||
|
|
||||||
#define OS_STRING VERSION_NAME "/1.0"
|
#define OS_STRING VERSION_NAME "/1.0"
|
||||||
#define MINIUPNPC_VERSION_STRING "2.1"
|
#define MINIUPNPC_VERSION_STRING "2.2.2"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* according to "UPnP Device Architecture 1.0" */
|
/* according to "UPnP Device Architecture 1.0" */
|
||||||
|
15
thirdparty/miniupnpc/miniupnpc/miniwget.c
vendored
15
thirdparty/miniupnpc/miniupnpc/miniwget.c
vendored
@ -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
|
/* Project : miniupnp
|
||||||
* Website : http://miniupnp.free.fr/
|
* Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define MAXHOSTNAMELEN 64
|
#define MAXHOSTNAMELEN 64
|
||||||
#define snprintf _snprintf
|
#include "win32_snprintf.h"
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
#ifndef strncasecmp
|
#ifndef strncasecmp
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
@ -176,11 +176,14 @@ getHTTPResponse(SOCKET s, int * size, int * status_code)
|
|||||||
/* Status line
|
/* Status line
|
||||||
* HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
|
* HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
|
||||||
int sp;
|
int sp;
|
||||||
for(sp = 0; sp < i; sp++)
|
for(sp = 0; sp < i - 1; sp++)
|
||||||
if(header_buf[sp] == ' ')
|
if(header_buf[sp] == ' ')
|
||||||
{
|
{
|
||||||
if(*status_code < 0)
|
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
|
else
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#if defined(__HAIKU__)
|
#if defined(__HAIKU__)
|
||||||
/* rename our private function because Haiku already defines a atoui() function */
|
/* rename our private function because Haiku already defines a atoui() function */
|
||||||
#define atoui atoui2
|
#define atoui atoui2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* list of the elements */
|
/* list of the elements */
|
||||||
static const struct {
|
static const struct {
|
||||||
|
10
thirdparty/miniupnpc/miniupnpc/receivedata.c
vendored
10
thirdparty/miniupnpc/miniupnpc/receivedata.c
vendored
@ -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
|
/* Project : miniupnp
|
||||||
* Website : http://miniupnp.free.fr/
|
* Website : http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
@ -92,7 +92,13 @@ receivedata(SOCKET socket,
|
|||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
if(scope_id)
|
if(scope_id)
|
||||||
*scope_id = src_addr6->sin6_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 */
|
#endif /* MINIUPNPC_GET_SRC_ADDR */
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
864
thirdparty/miniupnpc/miniupnpc/upnpc.c
vendored
864
thirdparty/miniupnpc/miniupnpc/upnpc.c
vendored
@ -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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#else
|
|
||||||
/* for IPPROTO_TCP / IPPROTO_UDP */
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#include <ctype.h>
|
|
||||||
#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; i<argc; i++)
|
|
||||||
{
|
|
||||||
if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h"))
|
|
||||||
{
|
|
||||||
command = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(argv[i][0] == '-')
|
|
||||||
{
|
|
||||||
if(argv[i][1] == 'u')
|
|
||||||
rootdescurl = argv[++i];
|
|
||||||
else if(argv[i][1] == 'm')
|
|
||||||
{
|
|
||||||
multicastif = argv[++i];
|
|
||||||
minissdpdpath = ""; /* Disable usage of minissdpd */
|
|
||||||
}
|
|
||||||
else if(argv[i][1] == 'z')
|
|
||||||
{
|
|
||||||
char junk;
|
|
||||||
if(sscanf(argv[++i], "%d%c", &localport, &junk)!=1 ||
|
|
||||||
localport<0 || localport>65535 ||
|
|
||||||
(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<commandargc)
|
|
||||||
{
|
|
||||||
if(!is_int(commandargv[i])) {
|
|
||||||
/* 1st parameter not an integer : error */
|
|
||||||
fprintf(stderr, "command -r : %s is not an port number\n", commandargv[i]);
|
|
||||||
retcode = 1;
|
|
||||||
break;
|
|
||||||
} else if(is_int(commandargv[i+1])){
|
|
||||||
/* 2nd parameter is an integer : <port> <external_port> <protocol> */
|
|
||||||
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 : <port> <protocol> */
|
|
||||||
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<commandargc; i++)
|
|
||||||
{
|
|
||||||
CheckPinhole(&urls, &data, commandargv[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'K':
|
|
||||||
for(i=0; i<commandargc; i++)
|
|
||||||
{
|
|
||||||
GetPinholePackets(&urls, &data, commandargv[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
for(i=0; i<commandargc; i++)
|
|
||||||
{
|
|
||||||
RemovePinhole(&urls, &data, commandargv[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
GetFirewallStatus(&urls, &data);
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
GetPinholeOutboundTimeout(&urls, &data,
|
|
||||||
commandargv[0], commandargv[1],
|
|
||||||
commandargv[2], commandargv[3],
|
|
||||||
commandargv[4]);
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
printf("Presentation URL found:\n");
|
|
||||||
printf(" %s\n", data.presentationurl);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unknown switch -%c\n", command);
|
|
||||||
retcode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeUPNPUrls(&urls);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
|
|
||||||
retcode = 1;
|
|
||||||
}
|
|
||||||
freeUPNPDevlist(devlist); devlist = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "No IGD UPnP Device found on the network !\n");
|
|
||||||
retcode = 1;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
nResult = WSACleanup();
|
|
||||||
if(nResult != NO_ERROR) {
|
|
||||||
fprintf(stderr, "WSACleanup() failed.\n");
|
|
||||||
}
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
16
thirdparty/miniupnpc/miniupnpc/upnpdev.h
vendored
16
thirdparty/miniupnpc/miniupnpc/upnpdev.h
vendored
@ -1,8 +1,8 @@
|
|||||||
/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */
|
/* $Id: upnpdev.h,v 1.3 2020/05/29 15:57:42 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Web : http://miniupnp.free.fr/
|
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
* copyright (c) 2005-2018 Thomas Bernard
|
* copyright (c) 2005-2020 Thomas Bernard
|
||||||
* This software is subjet to the conditions detailed in the
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENSE file. */
|
* provided LICENSE file. */
|
||||||
#ifndef UPNPDEV_H_INCLUDED
|
#ifndef UPNPDEV_H_INCLUDED
|
||||||
@ -20,7 +20,15 @@ struct UPNPDev {
|
|||||||
char * st;
|
char * st;
|
||||||
char * usn;
|
char * usn;
|
||||||
unsigned int scope_id;
|
unsigned int scope_id;
|
||||||
char buffer[3];
|
#if defined(__STDC_VERSION) && __STDC_VERSION__ >= 199901L
|
||||||
|
/* C99 flexible array member */
|
||||||
|
char buffer[];
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
char buffer[0];
|
||||||
|
#else
|
||||||
|
/* Fallback to a hack */
|
||||||
|
char buffer[1];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* freeUPNPDevlist()
|
/* freeUPNPDevlist()
|
||||||
|
112
thirdparty/miniupnpc/miniupnpc/upnperrors.c
vendored
112
thirdparty/miniupnpc/miniupnpc/upnperrors.c
vendored
@ -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 <string.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
26
thirdparty/miniupnpc/miniupnpc/upnperrors.h
vendored
26
thirdparty/miniupnpc/miniupnpc/upnperrors.h
vendored
@ -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
|
|
71
thirdparty/miniupnpc/miniupnpc/win32_snprintf.h
vendored
Normal file
71
thirdparty/miniupnpc/miniupnpc/win32_snprintf.h
vendored
Normal file
@ -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 <stdio.h>
|
||||||
|
|
||||||
|
/* 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 */
|
Loading…
Reference in New Issue
Block a user