From 415e2a0e26af19e00b7cafb58be72909ae1d8212 Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Sun, 25 Jan 2015 20:16:43 +0100 Subject: Update libminiupnpc to version 1.9 Fixes to our build of libminiupnpc: * do not build minissdpc.c on windows * if size of ip_mreqn is not defined, add -DNEED_STRUCT_IP_MREQN to the CFLAGS Test-Information: Verified it still builds. Change-Id: Idd3e19d6302cccc95fff0a01540b9abc1bc91e9e diff --git a/3rdParty/LibMiniUPnPc/SConscript b/3rdParty/LibMiniUPnPc/SConscript index 505060f..7e703f1 100644 --- a/3rdParty/LibMiniUPnPc/SConscript +++ b/3rdParty/LibMiniUPnPc/SConscript @@ -39,23 +39,27 @@ if env.get("LIBMINIUPNPC_BUNDLED", False) : if myenv["PLATFORM"] == "win32": myenv.Append(CCFLAGS = ["-DWIN32", "-D_WIN32_WINNT=0x0501"]) + if myenv["PLATFORM"] != "win32" and myenv["PLATFORM"] != "darwin": + conf = Configure(conf_env) + if conf.CheckTypeSize("ip_mreqn") == 0: + myenv.Append(CCFLAGS = ["-DNEED_STRUCT_IP_MREQN"]) + myenv.WriteVal("src/miniupnpc/miniupnpcstrings.h", myenv.Value( """ #ifndef __MINIUPNPCSTRINGS_H__ #define __MINIUPNPCSTRINGS_H__ #define OS_STRING "$OS_STRING" -#define MINIUPNPC_VERSION_STRING "1.5" +#define MINIUPNPC_VERSION_STRING "1.9" #endif """.replace("$OS_STRING", myenv["PLATFORM"]))) - env["LIBMINIUPNPC_OBJECTS"] = myenv.SwiftenObject([ + miniupnpc_objects = [ "src/miniupnpc/igd_desc_parse.c", "src/miniupnpc/miniupnpc.c", "src/miniupnpc/minixml.c", "src/miniupnpc/minisoap.c", - "src/miniupnpc/minissdpc.c", "src/miniupnpc/miniwget.c", #"src/miniupnpc/upnpc.c", "src/miniupnpc/upnpcommands.c", @@ -64,4 +68,9 @@ if env.get("LIBMINIUPNPC_BUNDLED", False) : "src/miniupnpc/connecthostport.c", "src/miniupnpc/portlistingparse.c", "src/miniupnpc/receivedata.c" - ]) + ] + + if myenv["PLATFORM"] != "win32": + miniupnpc_objects.append("src/miniupnpc/minissdpc.c") + + env["LIBMINIUPNPC_OBJECTS"] = myenv.SwiftenObject(miniupnpc_objects) diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/LICENSE b/3rdParty/LibMiniUPnPc/src/miniupnpc/LICENSE index 2434c86..ac89a75 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/LICENSE +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/LICENSE @@ -1,5 +1,5 @@ MiniUPnPc -Copyright (c) 2005-2011, Thomas BERNARD +Copyright (c) 2005-2011, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/bsdqueue.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/bsdqueue.h index 1fe0599..c6afe1f 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/bsdqueue.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/bsdqueue.h @@ -36,7 +36,7 @@ #define _SYS_QUEUE_H_ /* - * This file defines five types of data structures: singly-linked lists, + * This file defines five types of data structures: singly-linked lists, * lists, simple queues, tail queues, and circular queues. * * @@ -95,7 +95,7 @@ struct name { \ struct type *slh_first; /* first element */ \ } - + #define SLIST_HEAD_INITIALIZER(head) \ { NULL } @@ -107,7 +107,7 @@ struct name { \ struct { \ struct type *sle_next; /* next element */ \ } - + /* * Singly-linked List access methods. */ @@ -322,8 +322,8 @@ struct { \ struct type **tqe_prev; /* address of previous next element */ \ } -/* - * tail queue access methods +/* + * tail queue access methods */ #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_END(head) NULL @@ -430,7 +430,7 @@ struct { \ } /* - * Circular queue access methods + * Circular queue access methods */ #define CIRCLEQ_FIRST(head) ((head)->cqh_first) #define CIRCLEQ_LAST(head) ((head)->cqh_last) diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/codelength.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/codelength.h index f11e5e9..d342bd1 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/codelength.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/codelength.h @@ -1,18 +1,25 @@ -/* $Id: codelength.h,v 1.1 2008/10/06 22:04:06 nanard Exp $ */ +/* $Id: codelength.h,v 1.4 2012/09/27 15:40:29 nanard Exp $ */ /* Project : miniupnp * Author : Thomas BERNARD - * copyright (c) 2005-2008 Thomas Bernard + * copyright (c) 2005-2011 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ -#ifndef __CODELENGTH_H__ -#define __CODELENGTH_H__ +#ifndef CODELENGTH_H_INCLUDED +#define CODELENGTH_H_INCLUDED /* Encode length by using 7bit per Byte : * Most significant bit of each byte specifies that the * following byte is part of the code */ #define DECODELENGTH(n, p) n = 0; \ do { n = (n << 7) | (*p & 0x7f); } \ - while(*(p++)&0x80); + while((*(p++)&0x80) && (n<(1<<25))); + +#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \ + n = 0; \ + do { \ + if((p) >= (p_limit)) break; \ + n = (n << 7) | (*(p) & 0x7f); \ + } while((*((p)++)&0x80) && (n<(1<<25))); #define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.c index 7afd2b1..aabc7a6 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.c @@ -1,7 +1,7 @@ -/* $Id: connecthostport.c,v 1.5 2011/04/09 08:49:50 nanard Exp $ */ +/* $Id: connecthostport.c,v 1.11 2013/08/01 21:21:25 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2010-2011 Thomas Bernard + * Copyright (c) 2010-2013 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -13,7 +13,7 @@ #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #include #include @@ -21,12 +21,14 @@ #define snprintf _snprintf #define herror #define socklen_t int -#else /* #ifdef WIN32 */ +#else /* #ifdef _WIN32 */ #include #include +#include #include #define closesocket close #include +#include /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions * during the connect() call */ #define MINIUPNPC_IGNORE_EINTR @@ -34,10 +36,10 @@ #include #include #endif /* #ifndef USE_GETHOSTBYNAME */ -#endif /* #else WIN32 */ +#endif /* #else _WIN32 */ /* definition of PRINT_SOCKET_ERROR */ -#ifdef WIN32 +#ifdef _WIN32 #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) @@ -49,10 +51,15 @@ #include "connecthostport.h" +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + /* connecthostport() * return a socket connected (TCP) to the host and port * or -1 in case of error */ -int connecthostport(const char * host, unsigned short port) +int connecthostport(const char * host, unsigned short port, + unsigned int scope_id) { int s, n; #ifdef USE_GETHOSTBYNAME @@ -67,7 +74,7 @@ int connecthostport(const char * host, unsigned short port) #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT struct timeval timeout; #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - + #ifdef USE_GETHOSTBYNAME hp = gethostbyname(host); if(hp == NULL) @@ -85,13 +92,13 @@ int connecthostport(const char * host, unsigned short port) } #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT /* setting a 3 seconds timeout for the connect() call */ - timeout.tv_sec = 5; + timeout.tv_sec = 3; timeout.tv_usec = 0; if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } - timeout.tv_sec = 5; + timeout.tv_sec = 3; timeout.tv_usec = 0; if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) { @@ -145,10 +152,12 @@ int connecthostport(const char * host, unsigned short port) if(host[0] == '[') { /* literal ip v6 address */ - int i; - for(i = 0; host[i+1] && (host[i+1] != ']') && i < MAXHOSTNAMELEN; i++) + int i, j; + for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++) { - tmp_host[i] = host[i+1]; + tmp_host[i] = host[j]; + if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */ + j+=2; /* skip "25" */ } tmp_host[i] = '\0'; } @@ -160,7 +169,7 @@ int connecthostport(const char * host, unsigned short port) n = getaddrinfo(tmp_host, port_str, &hints, &ai); if(n != 0) { -#ifdef WIN32 +#ifdef _WIN32 fprintf(stderr, "getaddrinfo() error : %d\n", n); #else fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n)); @@ -173,15 +182,19 @@ int connecthostport(const char * host, unsigned short port) s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if(s < 0) continue; + if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) { + struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr; + addr6->sin6_scope_id = scope_id; + } #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT /* setting a 3 seconds timeout for the connect() call */ - timeout.tv_sec = 5; + timeout.tv_sec = 3; timeout.tv_usec = 0; if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } - timeout.tv_sec = 5; + timeout.tv_sec = 3; timeout.tv_usec = 0; if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) { diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.h index 57e24eb..56941d6 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/connecthostport.h @@ -1,17 +1,18 @@ -/* $Id: connecthostport.h,v 1.1 2010/04/04 23:21:03 nanard Exp $ */ +/* $Id: connecthostport.h,v 1.3 2012/09/27 15:42:10 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ * Author: Thomas Bernard - * Copyright (c) 2010 Thomas Bernard + * Copyright (c) 2010-2012 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ -#ifndef __CONNECTHOSTPORT_H__ -#define __CONNECTHOSTPORT_H__ +#ifndef CONNECTHOSTPORT_H_INCLUDED +#define CONNECTHOSTPORT_H_INCLUDED /* connecthostport() * return a socket connected (TCP) to the host and port * or -1 in case of error */ -int connecthostport(const char * host, unsigned short port); +int connecthostport(const char * host, unsigned short port, + unsigned int scope_id); #endif diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/declspec.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/declspec.h index b804247..f66b6d7 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/declspec.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/declspec.h @@ -1,7 +1,7 @@ -#ifndef __DECLSPEC_H__ -#define __DECLSPEC_H__ +#ifndef DECLSPEC_H_INCLUDED +#define DECLSPEC_H_INCLUDED -#if defined(WIN32) && !defined(STATICLIB) +#if defined(_WIN32) && !defined(STATICLIB) #ifdef MINIUPNP_EXPORTS #define LIBSPEC __declspec(dllexport) #else diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/igd_desc_parse.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/igd_desc_parse.h index bab1fd5..0a49b01 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/igd_desc_parse.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/igd_desc_parse.h @@ -1,4 +1,4 @@ -/* $Id: igd_desc_parse.h,v 1.10 2011/04/11 09:19:24 nanard Exp $ */ +/* $Id: igd_desc_parse.h,v 1.11 2012/10/16 16:49:02 nanard Exp $ */ /* Project : miniupnp * http://miniupnp.free.fr/ * Author : Thomas Bernard @@ -6,8 +6,8 @@ * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ -#ifndef __IGD_DESC_PARSE_H__ -#define __IGD_DESC_PARSE_H__ +#ifndef IGD_DESC_PARSE_H_INCLUDED +#define IGD_DESC_PARSE_H_INCLUDED /* Structure to store the result of the parsing of UPnP * descriptions of Internet Gateway Devices */ diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.c index 8889bf0..e45a481 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.c @@ -1,7 +1,7 @@ -/* $Id: minisoap.c,v 1.21 2011/03/22 19:15:35 nanard Exp $ */ +/* $Id: minisoap.c,v 1.22 2012/01/21 13:30:31 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2009 Thomas Bernard + * Copyright (c) 2005-2012 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * @@ -9,7 +9,7 @@ */ #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #include #define snprintf _snprintf @@ -24,7 +24,7 @@ /* only for malloc */ #include -#ifdef WIN32 +#ifdef _WIN32 #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) @@ -57,7 +57,7 @@ httpWrite(int fd, const char * body, int bodysize, /* disable send on the socket */ /* draytek routers dont seems to like that... */ #if 0 -#ifdef WIN32 +#ifdef _WIN32 if(shutdown(fd, SD_SEND)<0) { #else if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.h index 696725f..14c859d 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minisoap.h @@ -1,11 +1,11 @@ -/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */ +/* $Id: minisoap.h,v 1.5 2012/09/27 15:42:10 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard * Copyright (c) 2005 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ -#ifndef __MINISOAP_H__ -#define __MINISOAP_H__ +#ifndef MINISOAP_H_INCLUDED +#define MINISOAP_H_INCLUDED /*int httpWrite(int, const char *, int, const char *);*/ int soapPostSubmit(int, const char *, const char *, unsigned short, diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.c index a92c009..c4913fb 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.c @@ -1,33 +1,23 @@ -/* $Id: minissdpc.c,v 1.14 2010/11/25 09:57:25 nanard Exp $ */ +/* $Id: minissdpc.c,v 1.16 2012/03/05 19:42:46 nanard Exp $ */ /* Project : miniupnp + * Web : http://miniupnp.free.fr/ * Author : Thomas BERNARD - * copyright (c) 2005-2009 Thomas Bernard + * copyright (c) 2005-2012 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ /*#include */ #include #include #include - -#ifndef WIN32 #include #include -#else -#define ssize_t int -#endif - -#if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__) -#ifdef WIN32 +#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) +#ifdef _WIN32 #include #include #include #include -#if _MSC_VER >= 1600 #include -#else -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -#endif #endif #if defined(__amigaos__) || defined(__amigaos4__) #include @@ -130,7 +120,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath) p += stsize; tmp->buffer[urlsize+1+stsize] = '\0'; devlist = tmp; - /* added for compatibility with recent versions of MiniSSDPd + /* added for compatibility with recent versions of MiniSSDPd * >= 2007/12/19 */ DECODELENGTH(usnsize, p); p += usnsize; diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.h index 25e91ce..915b002 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minissdpc.h @@ -1,12 +1,12 @@ -/* $Id: minissdpc.h,v 1.1 2007/08/31 15:15:33 nanard Exp $ */ +/* $Id: minissdpc.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author: Thomas Bernard * Copyright (c) 2005-2007 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ -#ifndef __MINISSDPC_H__ -#define __MINISSDPC_H__ +#ifndef MINISSDPC_H_INCLUDED +#define MINISSDPC_H_INCLUDED struct UPNPDev * getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath); diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.c index bd46a24..a8a21f4 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.c @@ -1,7 +1,8 @@ -/* $Id: miniupnpc.c,v 1.95 2011/05/15 21:42:26 nanard Exp $ */ +/* $Id: miniupnpc.c,v 1.115 2013/12/13 12:02:24 nanard Exp $ */ /* Project : miniupnp + * Web : http://miniupnp.free.fr/ * Author : Thomas BERNARD - * copyright (c) 2005-2011 Thomas Bernard + * copyright (c) 2005-2013 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #define __EXTENSIONS__ 1 @@ -16,16 +17,21 @@ #endif #endif +#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(MACOSX) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) +#define HAS_IP_MREQN +#endif + #include #include #include -#ifdef WIN32 +#ifdef _WIN32 /* Win32 Specific includes and defines */ #include #include #include #include #define snprintf _snprintf +#define strdup _strdup #ifndef strncasecmp #if defined(_MSC_VER) && (_MSC_VER >= 1400) #define strncasecmp _memicmp @@ -34,7 +40,7 @@ #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* #ifndef strncasecmp */ #define MAXHOSTNAMELEN 64 -#else /* #ifdef WIN32 */ +#else /* #ifdef _WIN32 */ /* Standard POSIX includes */ #include #if defined(__amigaos__) && !defined(__amigaos4__) @@ -56,7 +62,7 @@ #include #include #define closesocket close -#endif /* #else WIN32 */ +#endif /* #else _WIN32 */ #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT #include #endif @@ -65,6 +71,17 @@ #define TIMEVAL struct timeval #endif + +#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) +/* Several versions of glibc don't define this structure, define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */ +struct ip_mreqn +{ + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_address; /* local IP address of interface */ + int imr_ifindex; /* Interface index */ +}; +#endif + #include "miniupnpc.h" #include "minissdpc.h" #include "miniwget.h" @@ -74,12 +91,16 @@ #include "connecthostport.h" #include "receivedata.h" -#ifdef WIN32 +#ifdef _WIN32 #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) #endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + #define SOAPPREFIX "s" #define SERVICEPREFIX "u" #define SERVICEPREFIX2 'u' @@ -184,12 +205,11 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service, strncpy(p, ">\r\n", soapbody + sizeof(soapbody) - p); } - if(!parseURL(url, hostname, &port, &path)) return NULL; - if(s<0) - { - s = connecthostport(hostname, port); - if(s < 0) - { + if(!parseURL(url, hostname, &port, &path, NULL)) return NULL; + if(s < 0) { + s = connecthostport(hostname, port, 0); + if(s < 0) { + /* failed to connect */ return NULL; } } @@ -225,8 +245,9 @@ char * simpleUPnPcommand(int s, const char * url, const char * service, { char * buf; +#if 1 buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); -/* +#else buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0"); if (!buf || *bufsize == 0) { @@ -235,7 +256,7 @@ char * simpleUPnPcommand(int s, const char * url, const char * service, #endif buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); } -*/ +#endif return buf; } @@ -322,8 +343,9 @@ upnpDiscover(int delay, const char * multicastif, { struct UPNPDev * tmp; struct UPNPDev * devlist = 0; + unsigned int scope_id = 0; int opt = 1; - static const char MSearchMsgFmt[] = + static const char MSearchMsgFmt[] = "M-SEARCH * HTTP/1.1\r\n" "HOST: %s:" XSTR(PORT) "\r\n" "ST: %s\r\n" @@ -353,14 +375,14 @@ upnpDiscover(int delay, const char * multicastif, int rv; struct addrinfo hints, *servinfo, *p; #endif -#ifdef WIN32 +#ifdef _WIN32 MIB_IPFORWARDROW ip_forward; #endif int linklocal = 1; if(error) *error = UPNPDISCOVER_UNKNOWN_ERROR; -#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) +#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) /* first try to get infos from minissdpd ! */ if(!minissdpdsock) minissdpdsock = "/var/run/minissdpd.sock"; @@ -378,7 +400,7 @@ upnpDiscover(int delay, const char * multicastif, deviceIndex = 0; #endif /* fallback to direct discovery */ -#ifdef WIN32 +#ifdef _WIN32 sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP); #else sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0); @@ -405,8 +427,8 @@ upnpDiscover(int delay, const char * multicastif, p->sin_port = htons(PORT); p->sin_addr.s_addr = INADDR_ANY; } -#ifdef WIN32 -/* This code could help us to use the right Network interface for +#ifdef _WIN32 +/* This code could help us to use the right Network interface for * SSDP multicast traffic */ /* Get IP associated with the index given in the ip_forward struct * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ @@ -465,7 +487,7 @@ upnpDiscover(int delay, const char * multicastif, } #endif -#ifdef WIN32 +#ifdef _WIN32 if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) #else if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) @@ -480,7 +502,7 @@ upnpDiscover(int delay, const char * multicastif, if(multicastif) { if(ipv6) { -#if !defined(WIN32) +#if !defined(_WIN32) /* according to MSDN, if_nametoindex() is supported since * MS Windows Vista and MS Windows Server 2008. * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ @@ -497,10 +519,28 @@ upnpDiscover(int delay, const char * multicastif, } else { struct in_addr mc_if; mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ - ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) + if(mc_if.s_addr != INADDR_NONE) { - PRINT_SOCKET_ERROR("setsockopt"); + ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } + } else { +#ifdef HAS_IP_MREQN + /* was not an ip address, try with an interface name */ + struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ + memset(&reqn, 0, sizeof(struct ip_mreqn)); + reqn.imr_ifindex = if_nametoindex(multicastif); + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } +#else +#ifdef DEBUG + printf("Setting of multicast interface not supported with interface name.\n"); +#endif +#endif } } } @@ -520,6 +560,10 @@ upnpDiscover(int delay, const char * multicastif, *error = UPNPDISCOVER_SUCCESS; /* Calculating maximum response time in seconds */ mx = ((unsigned int)delay) / 1000u; + if(mx == 0) { + mx = 1; + delay = 1000; + } /* receiving SSDP response packet */ for(n = 0; deviceList[deviceIndex]; deviceIndex++) { @@ -563,7 +607,7 @@ upnpDiscover(int delay, const char * multicastif, } #else /* #ifdef NO_GETADDRINFO */ memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET + hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */ hints.ai_socktype = SOCK_DGRAM; /*hints.ai_flags = */ if ((rv = getaddrinfo(ipv6 @@ -572,7 +616,7 @@ upnpDiscover(int delay, const char * multicastif, XSTR(PORT), &hints, &servinfo)) != 0) { if(error) *error = UPNPDISCOVER_SOCKET_ERROR; -#ifdef WIN32 +#ifdef _WIN32 fprintf(stderr, "getaddrinfo() failed: %d\n", rv); #else fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); @@ -582,6 +626,13 @@ upnpDiscover(int delay, const char * multicastif, for(p = servinfo; p; p = p->ai_next) { n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen); if (n < 0) { +#ifdef DEBUG + char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; + if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf, + sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { + fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf); + } +#endif PRINT_SOCKET_ERROR("sendto"); continue; } @@ -595,7 +646,7 @@ upnpDiscover(int delay, const char * multicastif, #endif /* #ifdef NO_GETADDRINFO */ } /* Waiting for SSDP REPLY packet to M-SEARCH */ - n = receivedata(sudp, bufr, sizeof(bufr), delay); + n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); if (n < 0) { /* error */ if(error) @@ -655,6 +706,7 @@ upnpDiscover(int delay, const char * multicastif, tmp->buffer[urlsize] = '\0'; memcpy(tmp->buffer + urlsize + 1, st, stsize); tmp->buffer[urlsize+1+stsize] = '\0'; + tmp->scope_id = scope_id; devlist = tmp; } } @@ -701,14 +753,31 @@ url_cpy_or_cat(char * dst, const char * src, int n) /* Prepare the Urls for usage... */ -LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, - const char * descURL) +LIBSPEC void +GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, + const char * descURL, unsigned int scope_id) { char * p; int n1, n2, n3, n4; +#ifdef IF_NAMESIZE + char ifname[IF_NAMESIZE]; +#else + char scope_str[8]; +#endif + n1 = strlen(data->urlbase); if(n1==0) n1 = strlen(descURL); + if(scope_id != 0) { +#ifdef IF_NAMESIZE + if(if_indextoname(scope_id, ifname)) { + n1 += 3 + strlen(ifname); /* 3 == strlen(%25) */ + } +#else + /* under windows, scope is numerical */ + snprintf(scope_str, sizeof(scope_str), "%u", scope_id); +#endif + } n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */ n2 = n1; n3 = n1; n4 = n1; n1 += strlen(data->first.scpdurl); @@ -716,21 +785,44 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, n3 += strlen(data->CIF.controlurl); n4 += strlen(data->IPv6FC.controlurl); + /* allocate memory to store URLs */ urls->ipcondescURL = (char *)malloc(n1); urls->controlURL = (char *)malloc(n2); urls->controlURL_CIF = (char *)malloc(n3); urls->controlURL_6FC = (char *)malloc(n4); - /* maintenant on chope la desc du WANIPConnection */ + + /* strdup descURL */ + urls->rootdescURL = strdup(descURL); + + /* get description of WANIPConnection */ if(data->urlbase[0] != '\0') strncpy(urls->ipcondescURL, data->urlbase, n1); else strncpy(urls->ipcondescURL, descURL, n1); p = strchr(urls->ipcondescURL+7, '/'); if(p) p[0] = '\0'; + if(scope_id != 0) { + if(0 == memcmp(urls->ipcondescURL, "http://[fe80:", 13)) { + /* this is a linklocal IPv6 address */ + p = strchr(urls->ipcondescURL, ']'); + if(p) { + /* insert %25 into URL */ +#ifdef IF_NAMESIZE + memmove(p + 3 + strlen(ifname), p, strlen(p) + 1); + memcpy(p, "%25", 3); + memcpy(p + 3, ifname, strlen(ifname)); +#else + memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1); + memcpy(p, "%25", 3); + memcpy(p + 3, scope_str, strlen(scope_str)); +#endif + } + } + } strncpy(urls->controlURL, urls->ipcondescURL, n2); strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3); strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4); - + url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1); url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2); @@ -764,6 +856,8 @@ FreeUPNPUrls(struct UPNPUrls * urls) urls->controlURL_CIF = 0; free(urls->controlURL_6FC); urls->controlURL_6FC = 0; + free(urls->rootdescURL); + urls->rootdescURL = 0; } int @@ -785,13 +879,14 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) /* UPNP_GetValidIGD() : * return values : + * -1 = Internal error * 0 = NO IGD found * 1 = A valid connected IGD has been found * 2 = A valid IGD has been found but it reported as * not connected * 3 = an UPnP device has been found but was not recognized as an IGD * - * In any non zero return case, the urls and data structures + * In any positive non zero return case, the urls and data structures * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to * free allocated memory. */ @@ -801,11 +896,17 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, struct IGDdatas * data, char * lanaddr, int lanaddrlen) { - char * descXML; - int descXMLsize = 0; + struct xml_desc { + char * xml; + int size; + int is_igd; + } * desc = NULL; struct UPNPDev * dev; int ndev = 0; - int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ + int i; + int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ + int n_igd = 0; + char extIpAddr[16]; if(!devlist) { #ifdef DEBUG @@ -813,35 +914,68 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, #endif return 0; } + /* counting total number of devices in the list */ + for(dev = devlist; dev; dev = dev->pNext) + ndev++; + if(ndev > 0) + { + desc = calloc(ndev, sizeof(struct xml_desc)); + if(!desc) + return -1; /* memory allocation error */ + } + /* Step 1 : downloading descriptions and testing type */ + for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) + { + /* we should choose an internet gateway device. + * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ + desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), + lanaddr, lanaddrlen, + dev->scope_id); +#ifdef DEBUG + if(!desc[i].xml) + { + printf("error getting XML description %s\n", dev->descURL); + } +#endif + if(desc[i].xml) + { + memset(data, 0, sizeof(struct IGDdatas)); + memset(urls, 0, sizeof(struct UPNPUrls)); + parserootdesc(desc[i].xml, desc[i].size, data); + if(0==strcmp(data->CIF.servicetype, + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) + { + desc[i].is_igd = 1; + n_igd++; + } + } + } + /* iterate the list to find a device depending on state */ for(state = 1; state <= 3; state++) { - for(dev = devlist; dev; dev = dev->pNext) + for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) { - /* we should choose an internet gateway device. - * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ - descXML = miniwget_getaddr(dev->descURL, &descXMLsize, - lanaddr, lanaddrlen); - if(descXML) + if(desc[i].xml) { - ndev++; memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(descXML, descXMLsize, data); - free(descXML); - descXML = NULL; - if(0==strcmp(data->CIF.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1") - || state >= 3 ) + parserootdesc(desc[i].xml, desc[i].size, data); + if(desc[i].is_igd || state >= 3 ) { - GetUPNPUrls(urls, data, dev->descURL); + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); + /* in state 2 and 3 we dont test if device is connected ! */ + if(state >= 2) + goto free_and_return; #ifdef DEBUG printf("UPNPIGD_IsConnected(%s) = %d\n", urls->controlURL, UPNPIGD_IsConnected(urls, data)); #endif - if((state >= 2) || UPNPIGD_IsConnected(urls, data)) - return state; + /* checks that status is connected AND there is a external IP address assigned */ + if(UPNPIGD_IsConnected(urls, data) + && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) + goto free_and_return; FreeUPNPUrls(urls); if(data->second.servicetype[0] != '\0') { #ifdef DEBUG @@ -852,28 +986,33 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); - GetUPNPUrls(urls, data, dev->descURL); + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); #ifdef DEBUG printf("UPNPIGD_IsConnected(%s) = %d\n", urls->controlURL, UPNPIGD_IsConnected(urls, data)); #endif - if((state >= 2) || UPNPIGD_IsConnected(urls, data)) - return state; + if(UPNPIGD_IsConnected(urls, data) + && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) + goto free_and_return; FreeUPNPUrls(urls); } } memset(data, 0, sizeof(struct IGDdatas)); } -#ifdef DEBUG - else - { - printf("error getting XML description %s\n", dev->descURL); + } + } + state = 0; +free_and_return: + if(desc) { + for(i = 0; i < ndev; i++) { + if(desc[i].xml) { + free(desc[i].xml); } -#endif } + free(desc); } - return 0; + return state; } /* UPNP_GetIGDFromUrl() @@ -890,14 +1029,14 @@ UPNP_GetIGDFromUrl(const char * rootdescurl, char * descXML; int descXMLsize = 0; descXML = miniwget_getaddr(rootdescurl, &descXMLsize, - lanaddr, lanaddrlen); + lanaddr, lanaddrlen, 0); if(descXML) { memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); parserootdesc(descXML, descXMLsize, data); free(descXML); descXML = NULL; - GetUPNPUrls(urls, data, rootdescurl); + GetUPNPUrls(urls, data, rootdescurl, 0); return 1; } else { return 0; diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.h index 50df017..b0d5d7f 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpc.h @@ -1,12 +1,12 @@ -/* $Id: miniupnpc.h,v 1.23 2011/04/11 08:21:46 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.35 2014/01/31 13:26:34 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ * Author: Thomas Bernard - * Copyright (c) 2005-2011 Thomas Bernard + * Copyright (c) 2005-2012 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ -#ifndef __MINIUPNPC_H__ -#define __MINIUPNPC_H__ +#ifndef MINIUPNPC_H_INCLUDED +#define MINIUPNPC_H_INCLUDED #include "declspec.h" #include "igd_desc_parse.h" @@ -17,6 +17,10 @@ #define UPNPDISCOVER_SOCKET_ERROR (-101) #define UPNPDISCOVER_MEMORY_ERROR (-102) +/* versions : */ +#define MINIUPNPC_VERSION "1.9" +#define MINIUPNPC_API_VERSION 10 + #ifdef __cplusplus extern "C" { #endif @@ -33,6 +37,7 @@ struct UPNPDev { struct UPNPDev * pNext; char * descURL; char * st; + unsigned int scope_id; char buffer[2]; }; @@ -74,6 +79,7 @@ struct UPNPUrls { char * ipcondescURL; char * controlURL_CIF; char * controlURL_6FC; + char * rootdescURL; }; /* UPNP_GetValidIGD() : @@ -105,9 +111,12 @@ UPNP_GetIGDFromUrl(const char * rootdescurl, struct IGDdatas * data, char * lanaddr, int lanaddrlen); -LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *); +LIBSPEC void +GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, + const char *, unsigned int); -LIBSPEC void FreeUPNPUrls(struct UPNPUrls *); +LIBSPEC void +FreeUPNPUrls(struct UPNPUrls *); /* return 0 or 1 */ LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpctypes.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpctypes.h index 86081c3..591c32f 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpctypes.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniupnpctypes.h @@ -1,11 +1,11 @@ -/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 nanard Exp $ */ +/* $Id: miniupnpctypes.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */ /* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org * Author : Thomas Bernard * Copyright (c) 2011 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided within this distribution */ -#ifndef __MINIUPNPCTYPES_H__ -#define __MINIUPNPCTYPES_H__ +#ifndef MINIUPNPCTYPES_H_INCLUDED +#define MINIUPNPCTYPES_H_INCLUDED #if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) #define UNSIGNED_INTEGER unsigned long long diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c index 0c31416..a75f55b 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c @@ -1,15 +1,16 @@ -/* $Id: miniwget.c,v 1.52 2011/06/17 22:59:42 nanard Exp $ */ +/* $Id: miniwget.c,v 1.60 2013/10/07 10:03:16 nanard Exp $ */ /* Project : miniupnp + * Website : http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2005-2011 Thomas Bernard + * Copyright (c) 2005-2013 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ - + #include #include #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #include #include @@ -24,7 +25,7 @@ #define strncasecmp memicmp #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* #ifndef strncasecmp */ -#else /* #ifdef WIN32 */ +#else /* #ifdef _WIN32 */ #include #include #if defined(__amigaos__) && !defined(__amigaos4__) @@ -33,26 +34,28 @@ #include #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ #include +#include #include +#include #include #define closesocket close /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions * during the connect() call */ #define MINIUPNPC_IGNORE_EINTR -#endif /* #else WIN32 */ +#endif /* #else _WIN32 */ #if defined(__sun) || defined(sun) #define MIN(x,y) (((x)<(y))?(x):(y)) #endif -#ifdef __ANDROID__ -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif - #include "miniupnpcstrings.h" #include "miniwget.h" #include "connecthostport.h" #include "receivedata.h" +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + /* * Read a HTTP response from a socket. * Process Content-Length and Transfer-encoding headers. @@ -71,20 +74,20 @@ getHTTPResponse(int s, int * size) unsigned int bytestocopy = 0; /* buffers : */ char * header_buf; - int header_buf_len = 2048; - int header_buf_used = 0; + unsigned int header_buf_len = 2048; + unsigned int header_buf_used = 0; char * content_buf; - int content_buf_len = 2048; - int content_buf_used = 0; + unsigned int content_buf_len = 2048; + unsigned int content_buf_used = 0; char chunksize_buf[32]; - int chunksize_buf_index; + unsigned int chunksize_buf_index; header_buf = malloc(header_buf_len); content_buf = malloc(content_buf_len); chunksize_buf[0] = '\0'; chunksize_buf_index = 0; - while((n = receivedata(s, buf, 2048, 5000)) > 0) + while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0) { if(endofheaders == 0) { @@ -101,14 +104,14 @@ getHTTPResponse(int s, int * size) /* search for CR LF CR LF (end of headers) * recognize also LF LF */ i = 0; - while(i < (header_buf_used-1) && (endofheaders == 0)) { + while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { if(header_buf[i] == '\r') { i++; if(header_buf[i] == '\n') { i++; - if(i < header_buf_used && header_buf[i] == '\r') { + if(i < (int)header_buf_used && header_buf[i] == '\r') { i++; - if(i < header_buf_used && header_buf[i] == '\n') { + if(i < (int)header_buf_used && header_buf[i] == '\n') { endofheaders = i+1; } } @@ -159,12 +162,12 @@ getHTTPResponse(int s, int * size) chunked = 1; } } - while(header_buf[i]=='\r' || header_buf[i] == '\n') + while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n')) i++; linestart = i; colon = linestart; valuestart = 0; - } + } } /* copy the remaining of the received data back to buf */ n = header_buf_used - endofheaders; @@ -198,7 +201,7 @@ getHTTPResponse(int s, int * size) i++; /* discarding chunk-extension */ if(i= '0' && chunksize_buf[j] <= '9') @@ -225,15 +228,15 @@ getHTTPResponse(int s, int * size) goto end_of_stream; } } - bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i); - if((int)(content_buf_used + bytestocopy) > content_buf_len) + bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i); + if((content_buf_used + bytestocopy) > content_buf_len) { - if(content_length >= content_buf_used + (int)bytestocopy) { + if(content_length >= (int)(content_buf_used + bytestocopy)) { content_buf_len = content_length; } else { - content_buf_len = content_buf_used + (int)bytestocopy; + content_buf_len = content_buf_used + bytestocopy; } - content_buf = (char *)realloc((void *)content_buf, + content_buf = (char *)realloc((void *)content_buf, content_buf_len); } memcpy(content_buf + content_buf_used, buf + i, bytestocopy); @@ -246,18 +249,18 @@ getHTTPResponse(int s, int * size) { /* not chunked */ if(content_length > 0 - && (content_buf_used + n) > content_length) { + && (int)(content_buf_used + n) > content_length) { /* skipping additional bytes */ n = content_length - content_buf_used; } if(content_buf_used + n > content_buf_len) { - if(content_length >= content_buf_used + n) { + if(content_length >= (int)(content_buf_used + n)) { content_buf_len = content_length; } else { content_buf_len = content_buf_used + n; } - content_buf = (char *)realloc((void *)content_buf, + content_buf = (char *)realloc((void *)content_buf, content_buf_len); } memcpy(content_buf + content_buf_used, buf, n); @@ -265,7 +268,7 @@ getHTTPResponse(int s, int * size) } } /* use the Content-Length header value if available */ - if(content_length > 0 && content_buf_used >= content_length) + if(content_length > 0 && (int)content_buf_used >= content_length) { #ifdef DEBUG printf("End of HTTP content\n"); @@ -288,10 +291,10 @@ end_of_stream: * do all the work. * Return NULL if something failed. */ static void * -miniwget3(const char * url, const char * host, +miniwget3(const char * host, unsigned short port, const char * path, int * size, char * addr_str, int addr_str_len, - const char * httpversion) + const char * httpversion, unsigned int scope_id) { char buf[2048]; int s; @@ -301,7 +304,7 @@ miniwget3(const char * url, const char * host, void * content; *size = 0; - s = connecthostport(host, port); + s = connecthostport(host, port, scope_id); if(s < 0) return NULL; @@ -347,7 +350,7 @@ miniwget3(const char * url, const char * host, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); if(n != 0) { -#ifdef WIN32 +#ifdef _WIN32 fprintf(stderr, "getnameinfo() failed : %d\n", n); #else fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); @@ -392,24 +395,29 @@ miniwget3(const char * url, const char * host, /* miniwget2() : * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ static void * -miniwget2(const char * url, const char * host, +miniwget2(const char * host, unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len) + int * size, char * addr_str, int addr_str_len, + unsigned int scope_id) { char * respbuffer; - respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1"); -/* - respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0"); +#if 1 + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.1", scope_id); +#else + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.0", scope_id); if (*size == 0) { #ifdef DEBUG printf("Retrying with HTTP/1.1\n"); #endif free(respbuffer); - respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1"); + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.1", scope_id); } -*/ +#endif return respbuffer; } @@ -421,12 +429,15 @@ miniwget2(const char * url, const char * host, * url : source string not modified * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) * port : port (destination) - * path : pointer to the path part of the URL + * path : pointer to the path part of the URL * * Return values : * 0 - Failure * 1 - Success */ -int parseURL(const char * url, char * hostname, unsigned short * port, char * * path) +int +parseURL(const char * url, + char * hostname, unsigned short * port, + char * * path, unsigned int * scope_id) { char * p1, *p2, *p3; if(!url) @@ -442,7 +453,43 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * * if(*p1 == '[') { /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ + char * scope; + scope = strchr(p1, '%'); p2 = strchr(p1, ']'); + if(p2 && scope && scope < p2 && scope_id) { + /* parse scope */ +#ifdef IF_NAMESIZE + char tmp[IF_NAMESIZE]; + int l; + scope++; + /* "%25" is just '%' in URL encoding */ + if(scope[0] == '2' && scope[1] == '5') + scope += 2; /* skip "25" */ + l = p2 - scope; + if(l >= IF_NAMESIZE) + l = IF_NAMESIZE - 1; + memcpy(tmp, scope, l); + tmp[l] = '\0'; + *scope_id = if_nametoindex(tmp); + if(*scope_id == 0) { + *scope_id = (unsigned int)strtoul(tmp, NULL, 10); + } +#else + /* under windows, scope is numerical */ + char tmp[8]; + int l; + scope++; + /* "%25" is just '%' in URL encoding */ + if(scope[0] == '2' && scope[1] == '5') + scope += 2; /* skip "25" */ + l = p2 - scope; + if(l >= sizeof(tmp)) + l = sizeof(tmp) - 1; + memcpy(tmp, scope, l); + tmp[l] = '\0'; + *scope_id = (unsigned int)strtoul(tmp, NULL, 10); +#endif + } p3 = strchr(p1, '/'); if(p2 && p3) { @@ -492,35 +539,40 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * * return 1; } -void * miniwget(const char * url, int * size) +void * +miniwget(const char * url, int * size, unsigned int scope_id) { unsigned short port; char * path; /* protocol://host:port/chemin */ char hostname[MAXHOSTNAMELEN+1]; *size = 0; - if(!parseURL(url, hostname, &port, &path)) + if(!parseURL(url, hostname, &port, &path, &scope_id)) return NULL; #ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path); + printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", + hostname, port, path, scope_id); #endif - return miniwget2(url, hostname, port, path, size, 0, 0); + return miniwget2(hostname, port, path, size, 0, 0, scope_id); } -void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen) +void * +miniwget_getaddr(const char * url, int * size, + char * addr, int addrlen, unsigned int scope_id) { unsigned short port; char * path; - /* protocol://host:port/chemin */ + /* protocol://host:port/path */ char hostname[MAXHOSTNAMELEN+1]; *size = 0; if(addr) addr[0] = '\0'; - if(!parseURL(url, hostname, &port, &path)) + if(!parseURL(url, hostname, &port, &path, &scope_id)) return NULL; #ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path); + printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", + hostname, port, path, scope_id); #endif - return miniwget2(url, hostname, port, path, size, addr, addrlen); + return miniwget2(hostname, port, path, size, addr, addrlen, scope_id); } diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.h index 8314b40..31bcea3 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.h @@ -1,12 +1,12 @@ -/* $Id: miniwget.h,v 1.6 2010/12/09 16:11:33 nanard Exp $ */ +/* $Id: miniwget.h,v 1.8 2012/09/27 15:42:10 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard + * Copyright (c) 2005-2012 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ -#ifndef __MINIWGET_H__ -#define __MINIWGET_H__ +#ifndef MINIWGET_H_INCLUDED +#define MINIWGET_H_INCLUDED #include "declspec.h" @@ -16,11 +16,11 @@ extern "C" { LIBSPEC void * getHTTPResponse(int s, int * size); -LIBSPEC void * miniwget(const char *, int *); +LIBSPEC void * miniwget(const char *, int *, unsigned int); -LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int); +LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int); -int parseURL(const char *, char *, unsigned short *, char * *); +int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); #ifdef __cplusplus } diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.c index 8b5594c..eb4d7d9 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.c @@ -1,10 +1,10 @@ -/* $Id: minixml.c,v 1.9 2011/02/07 13:44:57 nanard Exp $ */ +/* $Id: minixml.c,v 1.10 2012/03/05 19:42:47 nanard Exp $ */ /* minixml.c : the minimum size a xml parser can be ! */ /* Project : miniupnp * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author : Thomas Bernard -Copyright (c) 2005-2011, Thomas BERNARD +Copyright (c) 2005-2011, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without @@ -149,7 +149,7 @@ static void parseelt(struct xmlparser * p) return; } if(memcmp(p->xml, "xml += 9; data = p->xml; diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.h index 857c70e..9f43aa4 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minixml.h @@ -1,4 +1,4 @@ -/* $Id: minixml.h,v 1.6 2006/11/30 11:47:21 nanard Exp $ */ +/* $Id: minixml.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */ /* minimal xml parser * * Project : miniupnp @@ -8,8 +8,8 @@ * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ -#ifndef __MINIXML_H__ -#define __MINIXML_H__ +#ifndef MINIXML_H_INCLUDED +#define MINIXML_H_INCLUDED #define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) /* if a callback function pointer is set to NULL, diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/minixmlvalid.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/minixmlvalid.c index 766211b..0a112bf 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/minixmlvalid.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/minixmlvalid.c @@ -1,4 +1,4 @@ -/* $Id: minixmlvalid.c,v 1.4 2011/02/07 13:44:57 nanard Exp $ */ +/* $Id: minixmlvalid.c,v 1.6 2012/05/01 16:24:07 nanard Exp $ */ /* MiniUPnP Project * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ * minixmlvalid.c : @@ -32,7 +32,7 @@ int evtlistcmp(struct eventlist * a, struct eventlist * b) if(a->n != b->n) { printf("event number not matching : %d != %d\n", a->n, b->n); - //return 1; + /*return 1;*/ } for(i=0; in; i++) { @@ -82,7 +82,7 @@ static const struct event evtref[] = {ELTEND, "elt2b", 5}, {ELTEND, "elt2a", 5}, {ELTEND, "xmlroot", 7} -}; +}; void startelt(void * data, const char * p, int l) { @@ -148,6 +148,8 @@ int testxmlparser(const char * xml, int size) int main(int argc, char * * argv) { int r; + (void)argc; (void)argv; + r = testxmlparser(xmldata, sizeof(xmldata)-1); if(r) printf("minixml validation test failed\n"); diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.c index e09e80f..19e3054 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.c @@ -1,7 +1,7 @@ -/* $Id: portlistingparse.c,v 1.4 2011/03/18 11:02:17 nanard Exp $ */ +/* $Id: portlistingparse.c,v 1.6 2012/05/29 10:26:51 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011 Thomas Bernard + * (c) 2011 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ #include @@ -71,6 +71,8 @@ static void endelt(void * d, const char * name, int l) { struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; + (void)name; + (void)l; pdata->curelt = PortMappingEltNone; } diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.h index 1852478..bafa2a4 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/portlistingparse.h @@ -1,17 +1,17 @@ -/* $Id: portlistingparse.h,v 1.4 2011/02/15 23:03:56 nanard Exp $ */ +/* $Id: portlistingparse.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011 Thomas Bernard + * (c) 2011-2012 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ -#ifndef __PORTLISTINGPARSE_H__ -#define __PORTLISTINGPARSE_H__ +#ifndef PORTLISTINGPARSE_H_INCLUDED +#define PORTLISTINGPARSE_H_INCLUDED #include "declspec.h" /* for the definition of UNSIGNED_INTEGER */ #include "miniupnpctypes.h" -#if defined(NO_SYS_QUEUE_H) || defined(WIN32) || defined(__HAIKU__) +#if defined(NO_SYS_QUEUE_H) || defined(_WIN32) || defined(__HAIKU__) #include "bsdqueue.h" #else #include @@ -37,7 +37,7 @@ typedef enum { PortMappingEltNone, PortMappingEntry, NewRemoteHost, NewExternalPort, NewProtocol, NewInternalPort, NewInternalClient, - NewEnabled, NewDescription, + NewEnabled, NewDescription, NewLeaseTime } portMappingElt; struct PortMapping { diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.c index a1eadfc..ffbfbea 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.c @@ -1,12 +1,13 @@ -/* $Id: receivedata.c,v 1.1 2011/04/11 08:21:47 nanard Exp $ */ +/* $Id: receivedata.c,v 1.5 2013/10/07 09:48:36 nanard Exp $ */ /* Project : miniupnp + * Website : http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2011 Thomas Bernard + * Copyright (c) 2011-2012 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ #include -#ifdef WIN32 +#ifdef _WIN32 #include #include #else @@ -17,6 +18,7 @@ #include #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ #include +#include #if !defined(__amigaos__) && !defined(__amigaos4__) #include #endif @@ -24,7 +26,7 @@ #define MINIUPNPC_IGNORE_EINTR #endif -#ifdef WIN32 +#ifdef _WIN32 #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) @@ -33,10 +35,21 @@ #include "receivedata.h" int -receivedata(int socket, char * data, int length, int timeout) +receivedata(int socket, + char * data, int length, + int timeout, unsigned int * scope_id) { +#if MINIUPNPC_GET_SRC_ADDR +#ifdef DEBUG + /* to shut up valgrind about uninit value */ + struct sockaddr_storage src_addr = {0}; +#else + struct sockaddr_storage src_addr; +#endif + socklen_t src_addr_len = sizeof(src_addr); +#endif int n; -#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) +#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) /* using poll */ struct pollfd fds[1]; /* for the poll */ #ifdef MINIUPNPC_IGNORE_EINTR @@ -55,8 +68,8 @@ receivedata(int socket, char * data, int length, int timeout) /* timeout */ return 0; } -#else /* !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - /* using select under WIN32 and amigaos */ +#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ + /* using select under _WIN32 and amigaos */ fd_set socketSet; TIMEVAL timeval; FD_ZERO(&socketSet); @@ -69,12 +82,27 @@ receivedata(int socket, char * data, int length, int timeout) return -1; } else if(n == 0) { return 0; - } + } #endif +#if MINIUPNPC_GET_SRC_ADDR + n = recvfrom(socket, data, length, 0, + (struct sockaddr *)&src_addr, &src_addr_len); +#else n = recv(socket, data, length, 0); +#endif if(n<0) { PRINT_SOCKET_ERROR("recv"); } +#if MINIUPNPC_GET_SRC_ADDR + if (src_addr.ss_family == AF_INET6) { + const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr; +#ifdef DEBUG + printf("scope_id=%u\n", src_addr6->sin6_scope_id); +#endif + if(scope_id) + *scope_id = src_addr6->sin6_scope_id; + } +#endif return n; } diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.h index 7a551b9..0520a11 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/receivedata.h @@ -1,17 +1,19 @@ -/* $Id: receivedata.h,v 1.1 2011/04/11 08:21:47 nanard Exp $ */ +/* $Id: receivedata.h,v 1.4 2012/09/27 15:42:10 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author: Thomas Bernard - * Copyright (c) 2011 Thomas Bernard + * Copyright (c) 2011-2012 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ -#ifndef __RECEIVEDATA_H__ -#define __RECEIVEDATA_H__ +#ifndef RECEIVEDATA_H_INCLUDED +#define RECEIVEDATA_H_INCLUDED -/* Reads data from the specified socket. - * Returns the number of bytes read if successful, zero if no bytes were +/* Reads data from the specified socket. + * Returns the number of bytes read if successful, zero if no bytes were * read or if we timed out. Returns negative if there was an error. */ -int receivedata(int socket, char * data, int length, int timeout); +int receivedata(int socket, + char * data, int length, + int timeout, unsigned int * scope_id); #endif diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpc.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpc.c index b136d9d..9c9979a 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpc.c +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpc.c @@ -1,7 +1,7 @@ -/* $Id: upnpc.c,v 1.88 2011/06/17 23:31:01 nanard Exp $ */ +/* $Id: upnpc.c,v 1.101 2014/01/31 13:18:25 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2011 Thomas Bernard + * Copyright (c) 2005-2013 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -9,16 +9,19 @@ #include #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #define snprintf _snprintf +#else +/* for IPPROTO_TCP / IPPROTO_UDP */ +#include #endif #include "miniwget.h" #include "miniupnpc.h" #include "upnpcommands.h" #include "upnperrors.h" -/* protofix() checks if protocol is "UDP" or "TCP" +/* protofix() checks if protocol is "UDP" or "TCP" * returns NULL if not */ const char * protofix(const char * proto) { @@ -26,7 +29,7 @@ const char * protofix(const char * proto) 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]) + b = b && ( (proto[i] == proto_tcp[i]) || (proto[i] == (proto_tcp[i] | 32)) ); if(b) return proto_tcp; @@ -49,44 +52,47 @@ static void DisplayInfos(struct UPNPUrls * urls, unsigned int brUp, brDown; time_t timenow, timestarted; int r; - UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType); - if(connectionType[0]) + 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("GetConnectionTypeInfo failed.\n"); - UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr); - printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); + printf("Status : %s, uptime=%us, LastConnectionError : %s\n", + status, uptime, lastconnerr); timenow = time(NULL); timestarted = timenow - uptime; printf(" Time started : %s", ctime(×tarted)); - UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp); - 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); + 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"); } - printf("\n"); r = UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) - printf("GetExternalIPAddress() returned %d\n", r); - if(externalIPAddress[0]) + if(r != UPNPCOMMAND_SUCCESS) { + printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); + } else { printf("ExternalIPAddress = %s\n", externalIPAddress); - else - printf("GetExternalIPAddress failed.\n"); + } } static void GetConnectionStatus(struct UPNPUrls * urls, @@ -119,6 +125,7 @@ static void ListRedirections(struct UPNPUrls * urls, /*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'; @@ -166,6 +173,7 @@ static void NewListRedirections(struct UPNPUrls * urls, &pdata); if(r == UPNPCOMMAND_SUCCESS) { + printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next) { printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", @@ -209,7 +217,7 @@ static void NewListRedirections(struct UPNPUrls * urls, } } -/* Test function +/* Test function * 1 - get connection type * 2 - get extenal ip address * 3 - Add port mapping @@ -220,7 +228,8 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, const char * iport, const char * eport, const char * proto, - const char * leaseDuration) + const char * leaseDuration, + const char * description) { char externalIPAddress[40]; char intClient[40]; @@ -239,7 +248,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, fprintf(stderr, "invalid protocol\n"); return; } - + UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, externalIPAddress); @@ -247,22 +256,23 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, printf("ExternalIPAddress = %s\n", externalIPAddress); else printf("GetExternalIPAddress failed.\n"); - + r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, 0, proto, 0, leaseDuration); + eport, iport, iaddr, description, + proto, 0, leaseDuration); if(r!=UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", eport, iport, iaddr, r, strupnperror(r)); r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, data->first.servicetype, - eport, proto, + eport, proto, NULL/*remoteHost*/, intClient, intPort, NULL/*desc*/, NULL/*enabled*/, duration); if(r!=UPNPCOMMAND_SUCCESS) printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", r, strupnperror(r)); - + if(intClient[0]) { printf("InternalIP:Port = %s:%s\n", intClient, intPort); printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", @@ -301,7 +311,7 @@ static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) 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); @@ -310,7 +320,7 @@ static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); } -/* Test function +/* Test function * 1 - Add pinhole * 2 - Check if pinhole is working from the IGD side */ static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, @@ -319,27 +329,43 @@ static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, const char * proto, const char * lease_time) { char uniqueID[8]; - //int isWorking = 0; + /*int isWorking = 0;*/ int r; + char proto_tmp[8]; if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) { fprintf(stderr, "Wrong arguments\n"); return; } - /*proto = protofix(proto); - if(!proto) + if(atoi(proto) == 0) { - fprintf(stderr, "invalid protocol\n"); - return; - }*/ + 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", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); + remoteaddr, eport, intaddr, iport, r, strupnperror(r)); else { - printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", intaddr, iport, remoteaddr, eport, uniqueID); + 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)); @@ -374,7 +400,7 @@ static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, } } -/* Test function +/* Test function * Get pinhole timeout */ static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, @@ -463,8 +489,9 @@ int main(int argc, char ** argv) int retcode = 0; int error = 0; int ipv6 = 0; + const char * description = 0; -#ifdef WIN32 +#ifdef _WIN32 WSADATA wsaData; int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(nResult != NO_ERROR) @@ -473,12 +500,17 @@ int main(int argc, char ** argv) return -1; } #endif - printf("upnpc : miniupnpc library test client. (c) 2006-2011 Thomas Bernard\n"); + printf("upnpc : miniupnpc library test client. (c) 2005-2013 Thomas Bernard\n"); printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" "for more information.\n"); /* command line processing */ for(i=1; i 4)?commandargv[4]:"0"); + (commandargc > 4)?commandargv[4]:"0", + description); break; case 'd': for(i=0; itopelt = 1; if(l>63) l = 63; memcpy(data->curelt, name, l); data->curelt[l] = '\0'; + data->cdata = NULL; + data->cdatalen = 0; } static void -NameValueParserGetData(void * d, const char * datas, int l) +NameValueParserEndElt(void * d, const char * name, int l) { struct NameValueParserData * data = (struct NameValueParserData *)d; struct NameValue * nv; + (void)name; + (void)l; + if(!data->topelt) + return; + if(strcmp(data->curelt, "NewPortListing") != 0) + { + int l; + /* standard case. Limited to n chars strings */ + l = data->cdatalen; + nv = malloc(sizeof(struct NameValue)); + if(l>=(int)sizeof(nv->value)) + l = sizeof(nv->value) - 1; + strncpy(nv->name, data->curelt, 64); + nv->name[63] = '\0'; + if(data->cdata != NULL) + { + memcpy(nv->value, data->cdata, l); + nv->value[l] = '\0'; + } + else + { + nv->value[0] = '\0'; + } + LIST_INSERT_HEAD( &(data->head), nv, entries); + } + data->cdata = NULL; + data->cdatalen = 0; + data->topelt = 0; +} + +static void +NameValueParserGetData(void * d, const char * datas, int l) +{ + struct NameValueParserData * data = (struct NameValueParserData *)d; if(strcmp(data->curelt, "NewPortListing") == 0) { /* specific case for NewPortListing which is a XML Document */ @@ -42,15 +79,9 @@ NameValueParserGetData(void * d, const char * datas, int l) } else { - /* standard case. Limited to 63 chars strings */ - nv = malloc(sizeof(struct NameValue)); - if(l>63) - l = 63; - strncpy(nv->name, data->curelt, 64); - nv->name[63] = '\0'; - memcpy(nv->value, datas, l); - nv->value[l] = '\0'; - LIST_INSERT_HEAD( &(data->head), nv, entries); + /* standard case. */ + data->cdata = datas; + data->cdatalen = l; } } @@ -67,7 +98,7 @@ ParseNameValue(const char * buffer, int bufsize, parser.xmlsize = bufsize; parser.data = data; parser.starteltfunc = NameValueParserStartElt; - parser.endeltfunc = 0; + parser.endeltfunc = NameValueParserEndElt; parser.datafunc = NameValueParserGetData; parser.attfunc = 0; parsexml(&parser); @@ -90,7 +121,7 @@ ClearNameValueList(struct NameValueParserData * pdata) } } -char * +char * GetValueFromNameValueList(struct NameValueParserData * pdata, const char * Name) { @@ -131,7 +162,7 @@ GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, } #endif -/* debug all-in-one function +/* debug all-in-one function * do parsing then display to stdout */ #ifdef DEBUG void diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpreplyparse.h b/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpreplyparse.h index 267ea87..d4e3757 100644 --- a/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpreplyparse.h +++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/upnpreplyparse.h @@ -1,14 +1,14 @@ -/* $Id: upnpreplyparse.h,v 1.11 2011/02/07 16:17:06 nanard Exp $ */ +/* $Id: upnpreplyparse.h,v 1.17 2013/06/06 21:36:40 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2011 Thomas Bernard + * (c) 2006-2013 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ -#ifndef __UPNPREPLYPARSE_H__ -#define __UPNPREPLYPARSE_H__ +#ifndef UPNPREPLYPARSE_H_INCLUDED +#define UPNPREPLYPARSE_H_INCLUDED -#if defined(NO_SYS_QUEUE_H) || defined(WIN32) || defined(__HAIKU__) +#if defined(NO_SYS_QUEUE_H) || defined(_WIN32) || defined(__HAIKU__) #include "bsdqueue.h" #else #include @@ -21,7 +21,7 @@ extern "C" { struct NameValue { LIST_ENTRY(NameValue) entries; char name[64]; - char value[64]; + char value[128]; }; struct NameValueParserData { @@ -29,6 +29,9 @@ struct NameValueParserData { char curelt[64]; char * portListing; int portListingLength; + int topelt; + const char * cdata; + int cdatalen; }; /* ParseNameValue() */ @@ -45,10 +48,12 @@ char * GetValueFromNameValueList(struct NameValueParserData * pdata, const char * Name); +#if 0 /* GetValueFromNameValueListIgnoreNS() */ char * GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, const char * Name); +#endif /* DisplayNameValueList() */ #ifdef DEBUG -- cgit v0.10.2-6-g49f6