51 changes: 41 additions & 10 deletions 3rdparty/miniupnpc/connecthostport.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* $Id: connecthostport.c,v 1.3 2010/12/21 16:13:14 nanard Exp $ */
/* $Id: connecthostport.c,v 1.11 2013/08/01 21:21:25 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2010 Thomas Bernard
* Copyright (c) 2010-2013 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */

Expand All @@ -13,29 +13,33 @@

#include <string.h>
#include <stdio.h>
#ifdef WIN32
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#define MAXHOSTNAMELEN 64
#define snprintf _snprintf
#define herror
#define socklen_t int
#else /* #ifdef WIN32 */
#else /* #ifdef _WIN32 */
#include <unistd.h>
#include <sys/param.h>
#include <sys/select.h>
#include <errno.h>
#define closesocket close
#include <netdb.h>
#include <netinet/in.h>
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */
#define MINIUPNPC_IGNORE_EINTR
#ifndef USE_GETHOSTBYNAME
#include <sys/types.h>
#include <sys/socket.h>
#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)
Expand All @@ -47,24 +51,30 @@

#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
struct sockaddr_in dest;
struct hostent *hp;
#else /* #ifdef USE_GETHOSTBYNAME */
char tmp_host[MAXHOSTNAMELEN+1];
char port_str[8];
struct addrinfo *ai, *p;
struct addrinfo hints;
#endif /* #ifdef USE_GETHOSTBYNAME */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
struct timeval timeout;
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */

#ifdef USE_GETHOSTBYNAME
hp = gethostbyname(host);
if(hp == NULL)
Expand Down Expand Up @@ -139,10 +149,27 @@ int connecthostport(const char * host, unsigned short port)
hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
/* hints.ai_protocol = IPPROTO_TCP; */
snprintf(port_str, sizeof(port_str), "%hu", port);
n = getaddrinfo(host, port_str, &hints, &ai);
if(host[0] == '[')
{
/* literal ip v6 address */
int i, j;
for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
{
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';
}
else
{
strncpy(tmp_host, host, MAXHOSTNAMELEN);
}
tmp_host[MAXHOSTNAMELEN] = '\0';
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));
Expand All @@ -155,6 +182,10 @@ 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 = 3;
Expand Down
11 changes: 6 additions & 5 deletions 3rdparty/miniupnpc/connecthostport.h
Original file line number Diff line number Diff line change
@@ -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

6 changes: 3 additions & 3 deletions 3rdparty/miniupnpc/declspec.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down
13 changes: 12 additions & 1 deletion 3rdparty/miniupnpc/igd_desc_parse.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $Id: igd_desc_parse.c,v 1.11 2010/12/11 17:56:51 nanard Exp $ */
/* $Id: igd_desc_parse.c,v 1.14 2011/04/11 09:19:24 nanard Exp $ */
/* Project : miniupnp
* http://miniupnp.free.fr/
* Author : Thomas Bernard
Expand Down Expand Up @@ -46,6 +46,9 @@ void IGDendelt(void * d, const char * name, int l)
if(0==strcmp(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
} else if(0==strcmp(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1")) {
memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
} else if(0==strcmp(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANIPConnection:1")
|| 0==strcmp(datas->tmp.servicetype,
Expand All @@ -69,6 +72,8 @@ void IGDdata(void * d, const char * data, int l)
datas->level, datas->cureltname, l, data); */
if( !strcmp(datas->cureltname, "URLBase") )
dstmember = datas->urlbase;
else if( !strcmp(datas->cureltname, "presentationURL") )
dstmember = datas->presentationurl;
else if( !strcmp(datas->cureltname, "serviceType") )
dstmember = datas->tmp.servicetype;
else if( !strcmp(datas->cureltname, "controlURL") )
Expand Down Expand Up @@ -109,6 +114,12 @@ void printIGD(struct IGDdatas * d)
printf(" controlURL = '%s'\n", d->second.controlurl);
printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
printf(" SCPDURL = '%s'\n", d->second.scpdurl);
printf("WAN IPv6 Firewall Control :\n");
/*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
}


9 changes: 6 additions & 3 deletions 3rdparty/miniupnpc/igd_desc_parse.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* $Id: igd_desc_parse.h,v 1.7 2010/04/05 20:36:59 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
* Copyright (c) 2005-2010 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef __IGD_DESC_PARSE_H__
#define __IGD_DESC_PARSE_H__
#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 */
Expand All @@ -23,6 +23,7 @@ struct IGDdatas_service {
struct IGDdatas {
char cureltname[MINIUPNPC_URL_MAXSIZE];
char urlbase[MINIUPNPC_URL_MAXSIZE];
char presentationurl[MINIUPNPC_URL_MAXSIZE];
int level;
/*int state;*/
/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
Expand All @@ -32,6 +33,8 @@ struct IGDdatas {
struct IGDdatas_service first;
/* if both WANIPConnection and WANPPPConnection are present */
struct IGDdatas_service second;
/* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
struct IGDdatas_service IPv6FC;
/* tmp */
struct IGDdatas_service tmp;
};
Expand Down
13 changes: 7 additions & 6 deletions 3rdparty/miniupnpc/minisoap.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/* $Id: minisoap.c,v 1.20 2010/12/11 17:56:51 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.
*
* Minimal SOAP implementation for UPnP protocol.
*/
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#ifdef _WIN32
#include <io.h>
#include <winsock2.h>
#define snprintf _snprintf
Expand All @@ -24,7 +24,7 @@
/* only for malloc */
#include <stdlib.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)
Expand Down Expand Up @@ -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*/
Expand Down Expand Up @@ -112,7 +112,8 @@ int soapPostSubmit(int fd,
printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
url, httpversion, host, portstr);
printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
/*printf("%s", headerbuf);*/
printf("Headers :\n%s", headerbuf);
printf("Body :\n%s\n", body);
#endif
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
}
Expand Down
6 changes: 3 additions & 3 deletions 3rdparty/miniupnpc/minisoap.h
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
16 changes: 10 additions & 6 deletions 3rdparty/miniupnpc/minissdpc.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* $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 <syslog.h>*/
#include <lib/framework/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__)
#ifdef WIN32
#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
Expand Down Expand Up @@ -41,6 +41,10 @@ struct sockaddr_un {

#include "codelength.h"

#if defined(_MSC_VER)
typedef SSIZE_T ssize_t;
#endif

struct UPNPDev *
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
{
Expand Down Expand Up @@ -120,7 +124,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;
Expand Down
6 changes: 3 additions & 3 deletions 3rdparty/miniupnpc/minissdpc.h
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
630 changes: 346 additions & 284 deletions 3rdparty/miniupnpc/miniupnpc.c

Large diffs are not rendered by default.

48 changes: 32 additions & 16 deletions 3rdparty/miniupnpc/miniupnpc.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
/* $Id: miniupnpc.h,v 1.19 2009/10/10 19:15:35 nanard Exp $ */
/* $Id: miniupnpc.h,v 1.32 2013/02/06 14:44:42 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2005-2006 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"

/* error codes : */
#define UPNPDISCOVER_SUCCESS (0)
#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
#define UPNPDISCOVER_SOCKET_ERROR (-101)
#define UPNPDISCOVER_MEMORY_ERROR (-102)

/* versions : */
#define MINIUPNPC_VERSION "1.8.20131007"
#define MINIUPNPC_API_VERSION 9

#ifdef __cplusplus
extern "C" {
#endif

/* Structures definitions : */
struct UPNParg { const char * elt; const char * val; };

int simpleUPnPcommand(int, const char *, const char *,
const char *, struct UPNParg *,
char *, int *);
char *
simpleUPnPcommand(int, const char *, const char *,
const char *, struct UPNParg *,
int *);

struct UPNPDev {
struct UPNPDev * pNext;
char * descURL;
char * st;
unsigned int scope_id;
char buffer[2];
};

Expand All @@ -42,8 +54,11 @@ struct UPNPDev {
* multicast interface for sending SSDP discover packets.
* If sameport is not null, SSDP packets will be sent from the source port
* 1900 (same as destination port) otherwise system assign a source port. */
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock, int sameport);
LIBSPEC struct UPNPDev *
upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock, int sameport,
int ipv6,
int * error);
/* freeUPNPDevlist()
* free list returned by upnpDiscover() */
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
Expand All @@ -57,11 +72,14 @@ LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
* controlURL: controlURL of the WANIPConnection
* ipcondescURL: url of the description of the WANIPConnection
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
* controlURL_6FC: controlURL of the WANIPv6FirewallControl
*/
struct UPNPUrls {
char * controlURL;
char * ipcondescURL;
char * controlURL_CIF;
char * controlURL_6FC;
char * rootdescURL;
};

/* UPNP_GetValidIGD() :
Expand Down Expand Up @@ -93,14 +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 FreeUPNPUrls(struct UPNPUrls *);
LIBSPEC void
GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
const char *, unsigned int);

/* 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);
LIBSPEC void
FreeUPNPUrls(struct UPNPUrls *);

/* return 0 or 1 */
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
Expand Down
25 changes: 3 additions & 22 deletions 3rdparty/miniupnpc/miniupnpcstrings.h
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2005-2009 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __MINIUPNPCSTRINGS_H__
#define __MINIUPNPCSTRINGS_H__
#ifndef MINIUPNPCSTRINGS_H_INCLUDED
#define MINIUPNPCSTRINGS_H_INCLUDED

#include "lib/framework/wzglobal.h"

#if defined(WZ_OS_WIN32)
#define OS_STRING "Windows"
#elif defined (WZ_OS_MAC)
#define OS_STRING "Mac OS"
#elif defined(WZ_OS_LINUX)
#define OS_STRING "Linux"
#else
#define OS_STRING "Other/unknown"
#endif

#define MINIUPNPC_VERSION_STRING "1.5"
#define MINIUPNPC_VERSION_STRING "1.7"

#endif

19 changes: 19 additions & 0 deletions 3rdparty/miniupnpc/miniupnpctypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* $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_INCLUDED
#define MINIUPNPCTYPES_H_INCLUDED

#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
#define UNSIGNED_INTEGER unsigned long long
#define STRTOUI strtoull
#else
#define UNSIGNED_INTEGER unsigned int
#define STRTOUI strtoul
#endif

#endif

373 changes: 245 additions & 128 deletions 3rdparty/miniupnpc/miniwget.c

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions 3rdparty/miniupnpc/miniwget.h
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -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
}
Expand Down
43 changes: 34 additions & 9 deletions 3rdparty/miniupnpc/minixml.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* $Id: minixml.c,v 1.7 2009/10/10 19:15:35 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-2009, Thomas BERNARD
Copyright (c) 2005-2011, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand All @@ -30,6 +30,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "minixml.h"

/* parseatt : used to parse the argument list
Expand Down Expand Up @@ -143,18 +144,42 @@ static void parseelt(struct xmlparser * p)
return;
while( IS_WHITE_SPACE(*p->xml) )
{
p->xml++;
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
}
while(*p->xml!='<')
if(memcmp(p->xml, "<![CDATA[", 9) == 0)
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
/* CDATA handling */
p->xml += 9;
data = p->xml;
i = 0;
while(memcmp(p->xml, "]]>", 3) != 0)
{
i++; p->xml++;
if ((p->xml + 3) >= p->xmlend)
return;
}
if(i>0 && p->datafunc)
p->datafunc(p->data, data, i);
while(*p->xml!='<')
{
p->xml++;
if (p->xml >= p->xmlend)
return;
}
}
else
{
while(*p->xml!='<')
{
i++; p->xml++;
if ((p->xml + 1) >= p->xmlend)
return;
}
if(i>0 && p->datafunc && *(p->xml + 1) == '/')
p->datafunc(p->data, data, i);
}
if(i>0 && p->datafunc)
p->datafunc(p->data, data, i);
}
}
else if(*p->xml == '/')
Expand Down
6 changes: 3 additions & 3 deletions 3rdparty/miniupnpc/minixml.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
Expand Down
159 changes: 159 additions & 0 deletions 3rdparty/miniupnpc/portlistingparse.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* $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
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <string.h>
#include <stdlib.h>
#include "portlistingparse.h"
#include "minixml.h"

/* list of the elements */
static const struct {
const portMappingElt code;
const char * const str;
} elements[] = {
{ PortMappingEntry, "PortMappingEntry"},
{ NewRemoteHost, "NewRemoteHost"},
{ NewExternalPort, "NewExternalPort"},
{ NewProtocol, "NewProtocol"},
{ NewInternalPort, "NewInternalPort"},
{ NewInternalClient, "NewInternalClient"},
{ NewEnabled, "NewEnabled"},
{ NewDescription, "NewDescription"},
{ NewLeaseTime, "NewLeaseTime"},
{ PortMappingEltNone, NULL}
};

/* Helper function */
static UNSIGNED_INTEGER
atoui(const char * p, int l)
{
UNSIGNED_INTEGER r = 0;
while(l > 0 && *p)
{
if(*p >= '0' && *p <= '9')
r = r*10 + (*p - '0');
else
break;
p++;
l--;
}
return r;
}

/* Start element handler */
static void
startelt(void * d, const char * name, int l)
{
int i;
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
pdata->curelt = PortMappingEltNone;
for(i = 0; elements[i].str; i++)
{
if(memcmp(name, elements[i].str, l) == 0)
{
pdata->curelt = elements[i].code;
break;
}
}
if(pdata->curelt == PortMappingEntry)
{
struct PortMapping * pm;
pm = calloc(1, sizeof(struct PortMapping));
LIST_INSERT_HEAD( &(pdata->head), pm, entries);
}
}

/* End element handler */
static void
endelt(void * d, const char * name, int l)
{
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
(void)name;
(void)l;
pdata->curelt = PortMappingEltNone;
}

/* Data handler */
static void
data(void * d, const char * data, int l)
{
struct PortMapping * pm;
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
pm = pdata->head.lh_first;
if(!pm)
return;
if(l > 63)
l = 63;
switch(pdata->curelt)
{
case NewRemoteHost:
memcpy(pm->remoteHost, data, l);
pm->remoteHost[l] = '\0';
break;
case NewExternalPort:
pm->externalPort = (unsigned short)atoui(data, l);
break;
case NewProtocol:
if(l > 3)
l = 3;
memcpy(pm->protocol, data, l);
pm->protocol[l] = '\0';
break;
case NewInternalPort:
pm->internalPort = (unsigned short)atoui(data, l);
break;
case NewInternalClient:
memcpy(pm->internalClient, data, l);
pm->internalClient[l] = '\0';
break;
case NewEnabled:
pm->enabled = (unsigned char)atoui(data, l);
break;
case NewDescription:
memcpy(pm->description, data, l);
pm->description[l] = '\0';
break;
case NewLeaseTime:
pm->leaseTime = atoui(data, l);
break;
default:
break;
}
}


/* Parse the PortMappingList XML document for IGD version 2
*/
void
ParsePortListing(const char * buffer, int bufsize,
struct PortMappingParserData * pdata)
{
struct xmlparser parser;

memset(pdata, 0, sizeof(struct PortMappingParserData));
LIST_INIT(&(pdata->head));
/* init xmlparser */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = pdata;
parser.starteltfunc = startelt;
parser.endeltfunc = endelt;
parser.datafunc = data;
parser.attfunc = 0;
parsexml(&parser);
}

void
FreePortListing(struct PortMappingParserData * pdata)
{
struct PortMapping * pm;
while((pm = pdata->head.lh_first) != NULL)
{
LIST_REMOVE(pm, entries);
free(pm);
}
}

71 changes: 71 additions & 0 deletions 3rdparty/miniupnpc/portlistingparse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* $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-2012 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#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__)
#include "bsdqueue.h"
#else
#include <sys/queue.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* sample of PortMappingEntry :
<p:PortMappingEntry>
<p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
<p:NewExternalPort>2345</p:NewExternalPort>
<p:NewProtocol>TCP</p:NewProtocol>
<p:NewInternalPort>2345</p:NewInternalPort>
<p:NewInternalClient>192.168.1.137</p:NewInternalClient>
<p:NewEnabled>1</p:NewEnabled>
<p:NewDescription>dooom</p:NewDescription>
<p:NewLeaseTime>345</p:NewLeaseTime>
</p:PortMappingEntry>
*/
typedef enum { PortMappingEltNone,
PortMappingEntry, NewRemoteHost,
NewExternalPort, NewProtocol,
NewInternalPort, NewInternalClient,
NewEnabled, NewDescription,
NewLeaseTime } portMappingElt;

struct PortMapping {
LIST_ENTRY(PortMapping) entries;
UNSIGNED_INTEGER leaseTime;
unsigned short externalPort;
unsigned short internalPort;
char remoteHost[64];
char internalClient[64];
char description[64];
char protocol[4];
unsigned char enabled;
};

struct PortMappingParserData {
LIST_HEAD(portmappinglisthead, PortMapping) head;
portMappingElt curelt;
};

LIBSPEC void
ParsePortListing(const char * buffer, int bufsize,
struct PortMappingParserData * pdata);

LIBSPEC void
FreePortListing(struct PortMappingParserData * pdata);

#ifdef __cplusplus
}
#endif

#endif
109 changes: 109 additions & 0 deletions 3rdparty/miniupnpc/receivedata.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/* $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-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */

#include <stdio.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <unistd.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
#define socklen_t int
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
#include <netinet/in.h>
#if !defined(__amigaos__) && !defined(__amigaos4__)
#include <poll.h>
#endif
#include <errno.h>
#define MINIUPNPC_IGNORE_EINTR
#endif

#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
#endif

#include "receivedata.h"

int
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__)
/* using poll */
struct pollfd fds[1]; /* for the poll */
#ifdef MINIUPNPC_IGNORE_EINTR
do {
#endif
fds[0].fd = socket;
fds[0].events = POLLIN;
n = poll(fds, 1, timeout);
#ifdef MINIUPNPC_IGNORE_EINTR
} while(n < 0 && errno == EINTR);
#endif
if(n < 0) {
PRINT_SOCKET_ERROR("poll");
return -1;
} else if(n == 0) {
/* timeout */
return 0;
}
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
/* using select under _WIN32 and amigaos */
fd_set socketSet;
TIMEVAL timeval;
FD_ZERO(&socketSet);
FD_SET(socket, &socketSet);
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = (timeout % 1000) * 1000;
n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
if(n < 0) {
PRINT_SOCKET_ERROR("select");
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;
}


19 changes: 19 additions & 0 deletions 3rdparty/miniupnpc/receivedata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* $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-2012 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#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
* read or if we timed out. Returns negative if there was an error. */
int receivedata(int socket,
char * data, int length,
int timeout, unsigned int * scope_id);

#endif

604 changes: 545 additions & 59 deletions 3rdparty/miniupnpc/upnpcommands.c

Large diffs are not rendered by default.

121 changes: 99 additions & 22 deletions 3rdparty/miniupnpc/upnpcommands.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
/* $Id: upnpcommands.h,v 1.25 2012/09/27 15:42:10 nanard Exp $ */
/* Miniupnp project : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2010 Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided within this distribution */
#ifndef __UPNPCOMMANDS_H__
#define __UPNPCOMMANDS_H__
#ifndef UPNPCOMMANDS_H_INCLUDED
#define UPNPCOMMANDS_H_INCLUDED

#include "upnpreplyparse.h"
#include "portlistingparse.h"
#include "declspec.h"
#include "miniupnpctypes.h"

/* MiniUPnPc return codes : */
#define UPNPCOMMAND_SUCCESS (0)
Expand All @@ -20,14 +22,6 @@
extern "C" {
#endif

#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
#define UNSIGNED_INTEGER unsigned long long
#define STRTOUI strtoull
#else
#define UNSIGNED_INTEGER unsigned int
#define STRTOUI strtoul
#endif

LIBSPEC UNSIGNED_INTEGER
UPNP_GetTotalBytesSent(const char * controlURL,
const char * servicetype);
Expand Down Expand Up @@ -68,12 +62,12 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,

/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available
* at least 16 bytes must be available
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
*
*
* possible UPnP Errors :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control. */
Expand Down Expand Up @@ -101,7 +95,7 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
*
*
* List of possible UPnP errors for AddPortMapping :
* errorCode errorDescription (short) - Description (long)
* 402 Invalid Args - See UPnP Device Architecture section on Control.
Expand All @@ -112,7 +106,7 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
* 718 ConflictInMappingEntry - The port mapping entry specified conflicts
* with a mapping assigned previously to another client
* 724 SamePortValuesRequired - Internal and External port values
* must be the same
* must be the same
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
* permanent lease times on port mappings
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
Expand All @@ -126,7 +120,8 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * inClient,
const char * desc,
const char * proto,
const char * remoteHost);
const char * remoteHost,
const char * leaseDuration);

/* UPNP_DeletePortMapping()
* Use same argument values as what was used for AddPortMapping().
Expand All @@ -146,11 +141,20 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
/* UPNP_GetPortMappingNumberOfEntries()
* not supported by all routers */
LIBSPEC int
UPNP_GetPortMappingNumberOfEntries(const char* controlURL, const char* servicetype, unsigned int * num);
UPNP_GetPortMappingNumberOfEntries(const char* controlURL,
const char* servicetype,
unsigned int * num);

/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
* the result is returned in the intClient and intPort strings
* please provide 16 and 6 bytes of data
/* UPNP_GetSpecificPortMappingEntry()
* retrieves an existing port mapping
* params :
* in extPort
* in proto
* out intClient (16 bytes)
* out intPort (6 bytes)
* out desc (80 bytes)
* out enabled (4 bytes)
* out leaseDuration (16 bytes)
*
* return value :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
Expand All @@ -161,9 +165,22 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
const char * extPort,
const char * proto,
char * intClient,
char * intPort);
char * intPort,
char * desc,
char * enabled,
char * leaseDuration);

/* UPNP_GetGenericPortMappingEntry()
* params :
* in index
* out extPort (6 bytes)
* out intClient (16 bytes)
* out intPort (6 bytes)
* out protocol (4 bytes)
* out desc (80 bytes)
* out enabled (4 bytes)
* out rHost (64 bytes)
* out duration (16 bytes)
*
* return value :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
Expand All @@ -186,6 +203,66 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
char * rHost,
char * duration);

/* UPNP_GetListOfPortMappings() Available in IGD v2
*
*
* Possible UPNP Error codes :
* 606 Action not Authorized
* 730 PortMappingNotFound - no port mapping is found in the specified range.
* 733 InconsistantParameters - NewStartPort and NewEndPort values are not
* consistent.
*/
LIBSPEC int
UPNP_GetListOfPortMappings(const char * controlURL,
const char * servicetype,
const char * startPort,
const char * endPort,
const char * protocol,
const char * numberOfPorts,
struct PortMappingParserData * data);

/* IGD:2, functions for service WANIPv6FirewallControl:1 */
LIBSPEC int
UPNP_GetFirewallStatus(const char * controlURL,
const char * servicetype,
int * firewallEnabled,
int * inboundPinholeAllowed);

LIBSPEC int
UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
const char * remoteHost,
const char * remotePort,
const char * intClient,
const char * intPort,
const char * proto,
int * opTimeout);

LIBSPEC int
UPNP_AddPinhole(const char * controlURL, const char * servicetype,
const char * remoteHost,
const char * remotePort,
const char * intClient,
const char * intPort,
const char * proto,
const char * leaseTime,
char * uniqueID);

LIBSPEC int
UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
const char * uniqueID,
const char * leaseTime);

LIBSPEC int
UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);

LIBSPEC int
UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
const char * uniqueID, int * isWorking);

LIBSPEC int
UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
const char * uniqueID, int * packets);

#ifdef __cplusplus
}
#endif
Expand Down
42 changes: 40 additions & 2 deletions 3rdparty/miniupnpc/upnperrors.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $Id: upnperrors.c,v 1.3 2008/04/27 17:21:51 nanard Exp $ */
/* $Id: upnperrors.c,v 1.6 2012/03/15 01:02:03 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2007 Thomas Bernard
Expand All @@ -9,6 +9,7 @@
#include <string.h>
#include "upnperrors.h"
#include "upnpcommands.h"
#include "miniupnpc.h"

const char * strupnperror(int err)
{
Expand All @@ -23,6 +24,12 @@ const char * strupnperror(int err)
case UPNPCOMMAND_INVALID_ARGS:
s = "Miniupnpc Invalid Arguments";
break;
case UPNPDISCOVER_SOCKET_ERROR:
s = "Miniupnpc Socket error";
break;
case UPNPDISCOVER_MEMORY_ERROR:
s = "Miniupnpc Memory allocation error";
break;
case 401:
s = "Invalid Action";
break;
Expand All @@ -32,6 +39,36 @@ const char * strupnperror(int err)
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 = "WildcardNotPermittedInSrcIP";
break;
case 709:
s = "NoPacketSent";
break;
case 713:
s = "SpecifiedArrayIndexInvalid";
break;
Expand Down Expand Up @@ -60,7 +97,8 @@ const char * strupnperror(int err)
s = "ExternalPortOnlySupportsWildcard";
break;
default:
s = NULL;
s = "UnknownError";
break;
}
return s;
}
8 changes: 4 additions & 4 deletions 3rdparty/miniupnpc/upnperrors.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */
/* $Id: upnperrors.h,v 1.4 2012/09/27 15:42:11 nanard Exp $ */
/* (c) 2007 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__
#define __UPNPERRORS_H__
#ifndef UPNPERRORS_H_INCLUDED
#define UPNPERRORS_H_INCLUDED

#include "declspec.h"

Expand All @@ -15,7 +15,7 @@ extern "C" {
#endif

/* strupnperror()
* Return a string description of the UPnP error code
* Return a string description of the UPnP error code
* or NULL for undefinded errors */
LIBSPEC const char * strupnperror(int err);

Expand Down
88 changes: 72 additions & 16 deletions 3rdparty/miniupnpc/upnpreplyparse.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* $Id: upnpreplyparse.c,v 1.10 2008/02/21 13:05:27 nanard Exp $ */
/* $Id: upnpreplyparse.c,v 1.15 2013/06/06 21:36:40 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006 Thomas Bernard
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */

Expand All @@ -15,40 +15,90 @@
static void
NameValueParserStartElt(void * d, const char * name, int l)
{
struct NameValueParserData * data = (struct NameValueParserData *)d;
struct NameValueParserData * data = (struct NameValueParserData *)d;
data->topelt = 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;
nv = malloc(sizeof(struct NameValue));
if(l>63)
l = 63;
strncpy(nv->name, data->curelt, 64);
nv->name[63] = '\0';
memcpy(nv->value, datas, l);
nv->value[l] = '\0';
LIST_INSERT_HEAD( &(data->head), nv, entries);
(void)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 */
data->portListing = malloc(l + 1);
if(!data->portListing)
{
/* malloc error */
return;
}
memcpy(data->portListing, datas, l);
data->portListing[l] = '\0';
data->portListingLength = l;
}
else
{
/* standard case. */
data->cdata = datas;
data->cdatalen = l;
}
}

void
ParseNameValue(const char * buffer, int bufsize,
struct NameValueParserData * data)
struct NameValueParserData * data)
{
struct xmlparser parser;
LIST_INIT(&(data->head));
data->portListing = NULL;
data->portListingLength = 0;
/* init xmlparser object */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = data;
parser.starteltfunc = NameValueParserStartElt;
parser.endeltfunc = 0;
parser.endeltfunc = NameValueParserEndElt;
parser.datafunc = NameValueParserGetData;
parser.attfunc = 0;
parsexml(&parser);
Expand All @@ -58,14 +108,20 @@ void
ClearNameValueList(struct NameValueParserData * pdata)
{
struct NameValue * nv;
if(pdata->portListing)
{
free(pdata->portListing);
pdata->portListing = NULL;
pdata->portListingLength = 0;
}
while((nv = pdata->head.lh_first) != NULL)
{
LIST_REMOVE(nv, entries);
free(nv);
}
}

char *
char *
GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name)
{
Expand Down Expand Up @@ -106,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
Expand Down
19 changes: 13 additions & 6 deletions 3rdparty/miniupnpc/upnpreplyparse.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/* $Id: upnpreplyparse.h,v 1.10 2009/07/09 16:01:50 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-2009 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 <sys/queue.h>
Expand All @@ -21,12 +21,17 @@ extern "C" {
struct NameValue {
LIST_ENTRY(NameValue) entries;
char name[64];
char value[64];
char value[128];
};

struct NameValueParserData {
LIST_HEAD(listhead, NameValue) head;
char curelt[64];
char * portListing;
int portListingLength;
int topelt;
const char * cdata;
int cdatalen;
};

/* ParseNameValue() */
Expand All @@ -43,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
Expand Down
85 changes: 53 additions & 32 deletions lib/netplay/netplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,15 @@ static SocketSet* socket_set = NULL;

// UPnP
static int upnp = false;
static bool upnp_done = false;

WZ_THREAD *upnpdiscover;

static struct UPNPUrls urls;
static struct IGDdatas data;

// local ip address
static char lanaddr[16];
static char lanaddr[40];
static char externalIPAddress[40];
/**
* Used for connections with clients.
*/
Expand Down Expand Up @@ -934,22 +935,21 @@ static bool NETrecvGAMESTRUCT(GAMESTRUCT* ourgamestruct)
}



static int upnp_init(void *asdf)
{
struct UPNPDev *devlist;
struct UPNPDev *dev;
char *descXML;
int descXMLsize = 0;
char buf[255];

int result;
memset(&urls, 0, sizeof(struct UPNPUrls));
memset(&data, 0, sizeof(struct IGDdatas));

if (NetPlay.isUPNP)
{
debug(LOG_NET, "Searching for UPnP devices for automatic port forwarding...");
devlist = upnpDiscover(2000, NULL, NULL, 0);
devlist = upnpDiscover(3000, NULL, NULL, 0, 0, &result);
debug(LOG_NET, "UPnP device search finished.");
if (devlist)
{
Expand All @@ -967,13 +967,13 @@ static int upnp_init(void *asdf)

debug(LOG_NET, "UPnP device found: %s %s\n", dev->descURL, dev->st);

descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr));
descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr), dev->scope_id);
debug(LOG_NET, "LAN address: %s", lanaddr);
if (descXML)
{
parserootdesc (descXML, descXMLsize, &data);
free (descXML); descXML = 0;
GetUPNPUrls (&urls, &data, dev->descURL);
GetUPNPUrls (&urls, &data, dev->descURL, dev->scope_id);
}
ssprintf(buf, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr);
addDumpInfo(buf);
Expand All @@ -983,13 +983,20 @@ static int upnp_init(void *asdf)
{
ssprintf(buf, "controlURL not available, UPnP disabled");
addDumpInfo(buf);
ssprintf(buf, _("Your router doesn't support UPnP, you must manually configure your router & firewall to open port 2100 before you can host a game."));
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
return false;
}

NETaddRedirects();
upnp = true;
return true;
}
ssprintf(buf, "UPnP device not found.");
addDumpInfo(buf);
debug(LOG_NET, "No UPnP devices found.");
ssprintf(buf, _("No UPnP device was found. You must manually configure your router & firewall to open port 2100 before you can host a game."));
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
return false;
}
else
Expand All @@ -999,55 +1006,74 @@ static int upnp_init(void *asdf)
debug(LOG_NET, "UPnP detection routine disabled by user.");
return false;
}

}

static bool upnp_add_redirect(int port)
{
char externalIP[16];
char port_str[16];
char buf[512]={'\0'};
int r;

debug(LOG_NET, "upnp_add_redir(%d)\n", port);
UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP);
debug(LOG_NET, "upnp_add_redir(%d)", port);
sprintf(port_str, "%d", port);
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port_str, port_str, lanaddr, "Warzone 2100", "TCP", 0);
port_str, port_str, lanaddr, "Warzone 2100", "TCP", 0, "0"); // "0" = lease time unlimited
if (r != UPNPCOMMAND_SUCCESS)
{
debug(LOG_NET, "AddPortMapping(%s, %s, %s) failed\n", port_str, port_str, lanaddr);
ssprintf(buf, _("Could not open require port (%s) on (%s)"), port_str, lanaddr);
debug(LOG_NET, "%s", buf);
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
ssprintf(buf, _("You must manually configure your router & firewall to open port 2100 before you can host a game."));
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
return false;
}
return true;

r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS)
{
ssprintf(externalIPAddress, "???");
}
ssprintf(buf, _("Game configured port (%s) correctly on (%s). Your external IP is %s"), port_str, lanaddr, externalIPAddress);
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);

return true;
}

static void upnp_rem_redirect(int port)
static int upnp_rem_redirect(int port)
{
char port_str[16];
debug(LOG_NET, "upnp_rem_redir(%d)", port);
sprintf(port_str, "%d", port);
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", 0);
return UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL);
}

void NETaddRedirects(void)
{
debug(LOG_NET, "%s\n", __FUNCTION__);
if (!upnp_done)
if (upnp_add_redirect(gameserver_port))
{
upnp = wzThreadJoin(upnpdiscover);
upnp_done = true;
debug(LOG_NET, "successful!");
}
if (upnp) {
upnp_add_redirect(gameserver_port);
else
{
debug(LOG_NET, "failed!");
}
}

void NETremRedirects(void)
{
debug(LOG_NET, "%s\n", __FUNCTION__);
debug(LOG_NET, "upnp is %d", upnp);
if (upnp)
{
upnp_rem_redirect(gameserver_port);
int result = upnp_rem_redirect(gameserver_port);
if (!result)
{
debug(LOG_NET, "removed UPnP entry.");
}
else
{
debug(LOG_ERROR, "Failed to remove UPnP entry for the game. You must manually remove it from your router. (%d)", result);
}
}
}

Expand Down Expand Up @@ -1096,6 +1122,10 @@ int NETshutdown(void)
{
debug( LOG_NET, "NETshutdown" );
NETlogEntry("NETshutdown", SYNC_FLAG, selectedPlayer);
if (NetPlay.bComms && NetPlay.isUPNP)
{
NETremRedirects();
}
NETstopLogging();
if (IPlist)
free(IPlist);
Expand All @@ -1108,11 +1138,6 @@ int NETshutdown(void)
NETdeleteQueue();
SOCKETshutdown();

if (NetPlay.bComms && NetPlay.isUPNP)
{
NETremRedirects();
}

// Reset net usage statistics.
nStats = nZeroStats;
nStatsLastSec = nZeroStats;
Expand Down Expand Up @@ -2587,10 +2612,6 @@ bool NEThostGame(const char* SessionName, const char* PlayerName,
mapDownloadProgress = 100;
netPlayersUpdated = true;

if (NetPlay.bComms && NetPlay.isUPNP)
{
NETaddRedirects();
}
NET_InitPlayers();
for (unsigned n = 0; n < MAX_PLAYERS_IN_GUI; ++n)
{
Expand Down
5 changes: 5 additions & 0 deletions lib/netplay/netplay.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\3rdparty\miniupnpc\connecthostport.c" />
<ClCompile Include="..\..\3rdparty\miniupnpc\portlistingparse.c" />
<ClCompile Include="..\..\3rdparty\miniupnpc\receivedata.c" />
<ClCompile Include="netjoin_stub.cpp" />
<ClCompile Include="netlog.cpp" />
<ClCompile Include="netplay.cpp" />
Expand Down Expand Up @@ -246,8 +248,11 @@
<ClInclude Include="..\..\3rdparty\miniupnpc\minissdpc.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpc.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpcstrings.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpctypes.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\miniwget.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\minixml.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\portlistingparse.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\receivedata.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpcommands.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\upnperrors.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpreplyparse.h" />
Expand Down
15 changes: 15 additions & 0 deletions lib/netplay/netplay.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@
<ClCompile Include="netjoin_stub.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\3rdparty\miniupnpc\portlistingparse.c">
<Filter>Source Files\miniUPnP\src files</Filter>
</ClCompile>
<ClCompile Include="..\..\3rdparty\miniupnpc\receivedata.c">
<Filter>Source Files\miniUPnP\src files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\3rdparty\miniupnpc\bsdqueue.h">
Expand Down Expand Up @@ -127,5 +133,14 @@
<ClInclude Include="nettypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpctypes.h">
<Filter>Source Files\miniUPnP\header files</Filter>
</ClInclude>
<ClInclude Include="..\..\3rdparty\miniupnpc\portlistingparse.h">
<Filter>Source Files\miniUPnP\header files</Filter>
</ClInclude>
<ClInclude Include="..\..\3rdparty\miniupnpc\receivedata.h">
<Filter>Source Files\miniUPnP\header files</Filter>
</ClInclude>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,11 @@ bool runMultiPlayerMenu(void)
case FRONTEND_HOST:
// don't pretend we are running a network game. Really do it!
NetPlay.bComms = true; // use network = true
NETdiscoverUPnPDevices();
ingame.bHostSetup = true;
bMultiPlayer = true;
bMultiMessages = true;
NETinit(true);
NETdiscoverUPnPDevices();
game.type = SKIRMISH; // needed?
lastTitleMode = MULTI;
changeTitleMode(MULTIOPTION);
Expand Down
15 changes: 14 additions & 1 deletion src/multiint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3870,9 +3870,22 @@ bool startMultiOptions(bool bReenter)

addPlayerBox(false); // Players
addGameOptions();

addChatBox();

char buf[512]={'\0'};
if (NetPlay.isUPNP)
{
ssprintf(buf, _("UPnP detection is in progress..."));
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
}
else
{
ssprintf(buf, _("UPnP detection disabled by user. Autoconfig of port 2100 will not happen."));
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
}
ssprintf(buf, _("Press the start hosting button to begin hosting a game."));
addConsoleMessage(buf, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);

// going back to multiop after setting limits up..
if(bReenter && bHosted)
{
Expand Down