commit
2f217ab602
|
@ -1,6 +1,205 @@
|
|||
$Id: Changelog.txt,v 1.125 2010/12/21 16:13:13 nanard Exp $
|
||||
$Id: Changelog.txt,v 1.189 2013/10/07 10:04:55 nanard Exp $
|
||||
miniUPnP client Changelog.
|
||||
|
||||
2013/10/07:
|
||||
fixed potential buffer overrun in miniwget.c
|
||||
Modified UPNP_GetValidIGD() to check for ExternalIpAddress
|
||||
|
||||
2013/08/01:
|
||||
define MAXHOSTNAMELEN if not already done
|
||||
|
||||
2013/06/06:
|
||||
update upnpreplyparse to allow larger values (128 chars instead of 64)
|
||||
|
||||
2013/05/14:
|
||||
Update upnpreplyparse to take into account "empty" elements
|
||||
validate upnpreplyparse.c code with "make check"
|
||||
|
||||
2013/05/03:
|
||||
Fix Solaris build thanks to Maciej Małecki
|
||||
|
||||
2013/04/27:
|
||||
Fix testminiwget.sh for BSD
|
||||
|
||||
2013/03/23:
|
||||
Fixed Makefile for *BSD
|
||||
|
||||
2013/03/11:
|
||||
Update Makefile to use JNAerator version 0.11
|
||||
|
||||
2013/02/11:
|
||||
Fix testminiwget.sh for use with dash
|
||||
Use $(DESTDIR) in Makefile
|
||||
|
||||
VERSION 1.8 : released 2013/02/06
|
||||
|
||||
2012/10/16:
|
||||
fix testminiwget with no IPv6 support
|
||||
|
||||
2012/09/27:
|
||||
Rename all include guards to not clash with C99
|
||||
(7.1.3 Reserved identifiers).
|
||||
|
||||
2012/08/30:
|
||||
Added -e option to upnpc program (set description for port mappings)
|
||||
|
||||
2012/08/29:
|
||||
Python 3 support (thanks to Christopher Foo)
|
||||
|
||||
2012/08/11:
|
||||
Fix a memory link in UPNP_GetValidIGD()
|
||||
Try to handle scope id in link local IPv6 URL under MS Windows
|
||||
|
||||
2012/07/20:
|
||||
Disable HAS_IP_MREQN on DragonFly BSD
|
||||
|
||||
2012/06/28:
|
||||
GetUPNPUrls() now inserts scope into link-local IPv6 addresses
|
||||
|
||||
2012/06/23:
|
||||
More error return checks in upnpc.c
|
||||
#define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
|
||||
parseURL() now parses IPv6 addresses scope
|
||||
new parameter for miniwget() : IPv6 address scope
|
||||
increment API_VERSION to 9
|
||||
|
||||
2012/06/20:
|
||||
fixed CMakeLists.txt
|
||||
|
||||
2012/05/29
|
||||
Improvements in testminiwget.sh
|
||||
|
||||
VERSION 1.7 : released 2012/05/24
|
||||
|
||||
2012/05/01:
|
||||
Cleanup settings of CFLAGS in Makefile
|
||||
Fix signed/unsigned integer comparaisons
|
||||
|
||||
2012/04/20:
|
||||
Allow to specify protocol with TCP or UDP for -A option
|
||||
|
||||
2012/04/09:
|
||||
Only try to fetch XML description once in UPNP_GetValidIGD()
|
||||
Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments.
|
||||
|
||||
2012/04/05:
|
||||
minor improvements to minihttptestserver.c
|
||||
|
||||
2012/03/15:
|
||||
upnperrors.c returns valid error string for unrecognized error codes
|
||||
|
||||
2012/03/08:
|
||||
make minihttptestserver listen on loopback interface instead of 0.0.0.0
|
||||
|
||||
2012/01/25:
|
||||
Maven installation thanks to Alexey Kuznetsov
|
||||
|
||||
2012/01/21:
|
||||
Replace WIN32 macro by _WIN32
|
||||
|
||||
2012/01/19:
|
||||
Fixes in java wrappers thanks to Alexey Kuznetsov :
|
||||
https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc
|
||||
Make and install .deb packages (python) thanks to Alexey Kuznetsov :
|
||||
https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc
|
||||
|
||||
2012/01/07:
|
||||
The multicast interface can now be specified by name with IPv4.
|
||||
|
||||
2012/01/02:
|
||||
Install man page
|
||||
|
||||
2011/11/25:
|
||||
added header to Port Mappings list in upnpc.c
|
||||
|
||||
2011/10/09:
|
||||
Makefile : make clean now removes jnaerator generated files.
|
||||
MINIUPNPC_VERSION in miniupnpc.h (updated by make)
|
||||
|
||||
2011/09/12:
|
||||
added rootdescURL to UPNPUrls structure.
|
||||
|
||||
VERSION 1.6 : released 2011/07/25
|
||||
|
||||
2011/07/25:
|
||||
Update doc for version 1.6 release
|
||||
|
||||
2011/06/18:
|
||||
Fix for windows in miniwget.c
|
||||
|
||||
2011/06/04:
|
||||
display remote host in port mapping listing
|
||||
|
||||
2011/06/03:
|
||||
Fix in make install : there were missing headers
|
||||
|
||||
2011/05/26:
|
||||
Fix the socket leak in miniwget thanks to Richard Marsh.
|
||||
Permit to add leaseduration in -a command. Display lease duration.
|
||||
|
||||
2011/05/15:
|
||||
Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
|
||||
|
||||
2011/05/09:
|
||||
add a test in testminiwget.sh.
|
||||
more error checking in miniwget.c
|
||||
|
||||
2011/05/06:
|
||||
Adding some tool to test and validate miniwget.c
|
||||
simplified and debugged miniwget.c
|
||||
|
||||
2011/04/11:
|
||||
moving ReceiveData() to a receivedata.c file.
|
||||
parsing presentation url
|
||||
adding IGD v2 WANIPv6FirewallControl commands
|
||||
|
||||
2011/04/10:
|
||||
update of miniupnpcmodule.c
|
||||
comments in miniwget.c, update in testminiwget
|
||||
Adding errors codes from IGD v2
|
||||
new functions in upnpc.c for IGD v2
|
||||
|
||||
2011/04/09:
|
||||
Support for litteral ip v6 address in miniwget
|
||||
|
||||
2011/04/08:
|
||||
Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
|
||||
Updating APIVERSION
|
||||
Supporting IPV6 in upnpDiscover()
|
||||
Adding a -6 option to upnpc command line tool
|
||||
|
||||
2011/03/18:
|
||||
miniwget/parseURL() : return an error when url param is null.
|
||||
fixing GetListOfPortMappings()
|
||||
|
||||
2011/03/14:
|
||||
upnpDiscover() now reporting an error code.
|
||||
improvements in comments.
|
||||
|
||||
2011/03/11:
|
||||
adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
|
||||
|
||||
2011/02/15:
|
||||
Implementation of GetListOfPortMappings()
|
||||
|
||||
2011/02/07:
|
||||
updates to minixml to support character data starting with spaces
|
||||
minixml now support CDATA
|
||||
upnpreplyparse treats <NewPortListing> specificaly
|
||||
change in simpleUPnPcommand to return the buffer (simplification)
|
||||
|
||||
2011/02/06:
|
||||
Added leaseDuration argument to AddPortMapping()
|
||||
Starting to implement GetListOfPortMappings()
|
||||
|
||||
2011/01/11:
|
||||
updating wingenminiupnpcstrings.c
|
||||
|
||||
2011/01/04:
|
||||
improving updateminiupnpcstrings.sh
|
||||
|
||||
VERSION 1.5 : released 2011/01/01
|
||||
|
||||
2010/12/21:
|
||||
use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
|
||||
|
||||
|
@ -155,7 +354,7 @@ VERSION 1.2 :
|
|||
small modif to make Clang happy :)
|
||||
|
||||
2008/07/17:
|
||||
#define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
|
||||
#define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
|
||||
|
||||
2008/07/14:
|
||||
include declspec.h in installation (to /usr/include/miniupnpc)
|
||||
|
@ -177,7 +376,7 @@ VERSION 1.1 :
|
|||
improved python module error/exception reporting.
|
||||
|
||||
2008/04/23:
|
||||
Completely rewrite igd_desc_parse.c in order to be compatible with
|
||||
Completely rewrite igd_desc_parse.c in order to be compatible with
|
||||
Linksys WAG200G
|
||||
Added testigddescparse
|
||||
updated python module
|
||||
|
@ -200,7 +399,7 @@ VERSION 1.0 :
|
|||
improved make install :)
|
||||
|
||||
2007/12/22:
|
||||
Adding upnperrors.c/h to provide a strupnperror() function
|
||||
Adding upnperrors.c/h to provide a strupnperror() function
|
||||
used to translate UPnP error codes to string.
|
||||
|
||||
2007/12/19:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Copyright (c) 2005-2009, Thomas BERNARD
|
||||
MiniUPnPc
|
||||
Copyright (c) 2005-2011, Thomas BERNARD
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -18,8 +18,11 @@ noinst_HEADERS = \
|
|||
minissdpc.h \
|
||||
miniupnpc.h \
|
||||
miniupnpcstrings.h \
|
||||
miniupnpctypes.h \
|
||||
miniwget.h \
|
||||
minixml.h \
|
||||
portlistingparse.h \
|
||||
receivedata.h \
|
||||
upnpcommands.h \
|
||||
upnperrors.h \
|
||||
upnpreplyparse.h
|
||||
|
@ -32,6 +35,8 @@ libminiupnpc_a_SOURCES = \
|
|||
miniupnpc.c \
|
||||
miniwget.c \
|
||||
minixml.c \
|
||||
portlistingparse.c \
|
||||
receivedata.c \
|
||||
upnpcommands.c \
|
||||
upnperrors.c \
|
||||
upnpreplyparse.c
|
||||
|
|
|
@ -1,28 +1,35 @@
|
|||
Project: miniupnp
|
||||
Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
github: https://github.com/miniupnp/miniupnp
|
||||
freecode: http://freecode.com/projects/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
|
||||
LICENSE file provided within this distribution.
|
||||
|
||||
|
||||
For the comfort of Win32 users, bsdqueue.h is included in the distribution.
|
||||
Its licence is included in the header of the file.
|
||||
bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system.
|
||||
|
||||
* miniupnp Client *
|
||||
|
||||
* miniUPnP Client - miniUPnPc *
|
||||
|
||||
To compile, simply run 'gmake' (could be 'make' on your system).
|
||||
Under win32, to compile with MinGW, type "mingw32make.bat".
|
||||
MS Visual C solution and project files are supplied in the msvc/ subdirectory.
|
||||
|
||||
The compilation is known to work under linux, FreeBSD,
|
||||
OpenBSD, MacOS X, AmigaOS and cygwin.
|
||||
The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
|
||||
upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
|
||||
|
||||
To install the library and headers on the system use :
|
||||
> su
|
||||
> make install
|
||||
> exit
|
||||
|
||||
alternatively, to install in a specific location, use :
|
||||
alternatively, to install into a specific location, use :
|
||||
> INSTALLPREFIX=/usr/local make install
|
||||
|
||||
upnpc.c is a sample client using the libminiupnpc.
|
||||
|
@ -40,9 +47,10 @@ and -lminiupnpc for the link
|
|||
|
||||
Discovery process is speeded up when MiniSSDPd is running on the machine.
|
||||
|
||||
|
||||
* Python module *
|
||||
|
||||
you can build a python module with 'make pythonmodule'
|
||||
you can build a python module with 'make pythonmodule'
|
||||
and install it with 'make installpythonmodule'.
|
||||
setup.py (and setupmingw32.py) are included in the distribution.
|
||||
|
||||
|
@ -53,4 +61,6 @@ e-mail : miniupnp@free.fr
|
|||
If you are using libminiupnpc in your application, please
|
||||
send me an email !
|
||||
|
||||
For any question, you can use the web forum :
|
||||
http://miniupnp.tuxfamily.org/forum/
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
@ -13,18 +13,22 @@
|
|||
|
||||
#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
|
||||
|
@ -32,10 +36,10 @@
|
|||
#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)
|
||||
|
@ -47,16 +51,22 @@
|
|||
|
||||
#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;
|
||||
|
@ -64,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)
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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") )
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $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
|
||||
|
@ -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 */
|
||||
|
@ -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" */
|
||||
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $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.
|
||||
*
|
||||
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <winsock2.h>
|
||||
#define snprintf _snprintf
|
||||
|
@ -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)
|
||||
|
@ -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*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,26 @@
|
|||
/* $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
|
||||
|
@ -18,14 +28,16 @@ extern "C" {
|
|||
/* 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];
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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() :
|
||||
|
@ -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
|
||||
GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
|
||||
const char *, unsigned int);
|
||||
|
||||
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
|
||||
|
||||
/* Reads data from the specified socket.
|
||||
* Returns the number of bytes read if successful, zero if no bytes were
|
||||
* read or if we timed out. Returns negative if there was an error. */
|
||||
int ReceiveData(int socket, char * data, int length, int timeout);
|
||||
LIBSPEC void
|
||||
FreeUPNPUrls(struct UPNPUrls *);
|
||||
|
||||
/* return 0 or 1 */
|
||||
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
/* $Id: miniwget.c,v 1.41 2010/12/12 23:52:02 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-2010 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "miniupnpc.h"
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <io.h>
|
||||
|
@ -18,12 +18,14 @@
|
|||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
#define snprintf _snprintf
|
||||
#define socklen_t int
|
||||
#ifndef strncasecmp
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#define strncasecmp _memicmp
|
||||
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||
#define strncasecmp memicmp
|
||||
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||
#else /* #ifdef WIN32 */
|
||||
#endif /* #ifndef strncasecmp */
|
||||
#else /* #ifdef _WIN32 */
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#if defined(__amigaos__) && !defined(__amigaos4__)
|
||||
|
@ -32,13 +34,15 @@
|
|||
#include <sys/select.h>
|
||||
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#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
|
||||
|
@ -46,35 +50,46 @@
|
|||
#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.
|
||||
* return a pointer to the content buffer, which length is saved
|
||||
* to the length parameter.
|
||||
*/
|
||||
void *
|
||||
getHTTPResponse(int s, int * size)
|
||||
{
|
||||
char buf[2048];
|
||||
int n;
|
||||
int headers = 1;
|
||||
int endofheaders = 0;
|
||||
int chunked = 0;
|
||||
int content_length = -1;
|
||||
unsigned int chunksize = 0;
|
||||
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];
|
||||
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(headers)
|
||||
if(endofheaders == 0)
|
||||
{
|
||||
int i;
|
||||
int linestart=0;
|
||||
|
@ -86,17 +101,43 @@ getHTTPResponse(int s, int * size)
|
|||
}
|
||||
memcpy(header_buf + header_buf_used, buf, n);
|
||||
header_buf_used += n;
|
||||
for(i = 0; i < (header_buf_used-3); i++) {
|
||||
/* search for CR LF CR LF (end of headers)
|
||||
* recognize also LF LF */
|
||||
i = 0;
|
||||
while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
|
||||
if(header_buf[i] == '\r') {
|
||||
i++;
|
||||
if(header_buf[i] == '\n') {
|
||||
i++;
|
||||
if(i < (int)header_buf_used && header_buf[i] == '\r') {
|
||||
i++;
|
||||
if(i < (int)header_buf_used && header_buf[i] == '\n') {
|
||||
endofheaders = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(header_buf[i] == '\n') {
|
||||
i++;
|
||||
if(header_buf[i] == '\n') {
|
||||
endofheaders = i+1;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(endofheaders == 0)
|
||||
continue;
|
||||
/* parse header lines */
|
||||
for(i = 0; i < endofheaders - 1; i++) {
|
||||
if(colon <= linestart && header_buf[i]==':')
|
||||
{
|
||||
colon = i;
|
||||
while(i < (n-3)
|
||||
while(i < (endofheaders-1)
|
||||
&& (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
|
||||
i++;
|
||||
valuestart = i + 1;
|
||||
}
|
||||
/* detecting end of line */
|
||||
else if(header_buf[i]=='\r' && header_buf[i+1]=='\n')
|
||||
else if(header_buf[i]=='\r' || header_buf[i]=='\n')
|
||||
{
|
||||
if(colon > linestart && valuestart > colon)
|
||||
{
|
||||
|
@ -113,7 +154,7 @@ getHTTPResponse(int s, int * size)
|
|||
#endif
|
||||
}
|
||||
else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
|
||||
&& 0==strncasecmp(buf+valuestart, "chunked", 7))
|
||||
&& 0==strncasecmp(header_buf+valuestart, "chunked", 7))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("chunked transfer-encoding!\n");
|
||||
|
@ -121,76 +162,19 @@ getHTTPResponse(int s, int * size)
|
|||
chunked = 1;
|
||||
}
|
||||
}
|
||||
linestart = i+2;
|
||||
while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
|
||||
i++;
|
||||
linestart = i;
|
||||
colon = linestart;
|
||||
valuestart = 0;
|
||||
}
|
||||
/* searching for the end of the HTTP headers */
|
||||
if(header_buf[i]=='\r' && header_buf[i+1]=='\n'
|
||||
&& header_buf[i+2]=='\r' && header_buf[i+3]=='\n')
|
||||
{
|
||||
headers = 0; /* end */
|
||||
i += 4;
|
||||
if(i < header_buf_used)
|
||||
{
|
||||
if(chunked)
|
||||
{
|
||||
while(i<header_buf_used)
|
||||
{
|
||||
while(i<header_buf_used && isxdigit(header_buf[i]))
|
||||
{
|
||||
if(header_buf[i] >= '0' && header_buf[i] <= '9')
|
||||
chunksize = (chunksize << 4) + (header_buf[i] - '0');
|
||||
else
|
||||
chunksize = (chunksize << 4) + ((header_buf[i] | 32) - 'a' + 10);
|
||||
i++;
|
||||
}
|
||||
/* discarding chunk-extension */
|
||||
while(i < header_buf_used && header_buf[i] != '\r') i++;
|
||||
if(i < header_buf_used && header_buf[i] == '\r') i++;
|
||||
if(i < header_buf_used && header_buf[i] == '\n') i++;
|
||||
#ifdef DEBUG
|
||||
printf("chunksize = %u (%x)\n", chunksize, chunksize);
|
||||
#endif
|
||||
if(chunksize == 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("end of HTTP content !\n");
|
||||
#endif
|
||||
goto end_of_stream;
|
||||
}
|
||||
bytestocopy = ((int)chunksize < header_buf_used - i)?chunksize:(header_buf_used - i);
|
||||
#ifdef DEBUG
|
||||
printf("chunksize=%u bytestocopy=%u (i=%d header_buf_used=%d)\n",
|
||||
chunksize, bytestocopy, i, header_buf_used);
|
||||
#endif
|
||||
if(content_buf_len < (int)(content_buf_used + bytestocopy))
|
||||
{
|
||||
content_buf = realloc(content_buf, content_buf_used + bytestocopy);
|
||||
content_buf_len = content_buf_used + bytestocopy;
|
||||
}
|
||||
memcpy(content_buf + content_buf_used, header_buf + i, bytestocopy);
|
||||
content_buf_used += bytestocopy;
|
||||
chunksize -= bytestocopy;
|
||||
i += bytestocopy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(content_buf_len < header_buf_used - i)
|
||||
{
|
||||
content_buf = realloc(content_buf, header_buf_used - i);
|
||||
content_buf_len = header_buf_used - i;
|
||||
}
|
||||
memcpy(content_buf, header_buf + i, header_buf_used - i);
|
||||
content_buf_used = header_buf_used - i;
|
||||
i = header_buf_used;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* copy the remaining of the received data back to buf */
|
||||
n = header_buf_used - endofheaders;
|
||||
memcpy(buf, header_buf + endofheaders, n);
|
||||
/* if(headers) */
|
||||
}
|
||||
else
|
||||
if(endofheaders)
|
||||
{
|
||||
/* content */
|
||||
if(chunked)
|
||||
|
@ -201,19 +185,37 @@ getHTTPResponse(int s, int * size)
|
|||
if(chunksize == 0)
|
||||
{
|
||||
/* reading chunk size */
|
||||
if(i<n && buf[i] == '\r') i++;
|
||||
if(i<n && buf[i] == '\n') i++;
|
||||
while(i<n && isxdigit(buf[i]))
|
||||
if(chunksize_buf_index == 0) {
|
||||
/* skipping any leading CR LF */
|
||||
if(i<n && buf[i] == '\r') i++;
|
||||
if(i<n && buf[i] == '\n') i++;
|
||||
}
|
||||
while(i<n && isxdigit(buf[i])
|
||||
&& chunksize_buf_index < (sizeof(chunksize_buf)-1))
|
||||
{
|
||||
if(buf[i] >= '0' && buf[i] <= '9')
|
||||
chunksize = (chunksize << 4) + (buf[i] - '0');
|
||||
else
|
||||
chunksize = (chunksize << 4) + ((buf[i] | 32) - 'a' + 10);
|
||||
chunksize_buf[chunksize_buf_index++] = buf[i];
|
||||
chunksize_buf[chunksize_buf_index] = '\0';
|
||||
i++;
|
||||
}
|
||||
while(i<n && buf[i] != '\r') i++; /* discarding chunk-extension */
|
||||
while(i<n && buf[i] != '\r' && buf[i] != '\n')
|
||||
i++; /* discarding chunk-extension */
|
||||
if(i<n && buf[i] == '\r') i++;
|
||||
if(i<n && buf[i] == '\n') i++;
|
||||
if(i<n && buf[i] == '\n') {
|
||||
unsigned int j;
|
||||
for(j = 0; j < chunksize_buf_index; j++) {
|
||||
if(chunksize_buf[j] >= '0'
|
||||
&& chunksize_buf[j] <= '9')
|
||||
chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
|
||||
else
|
||||
chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
|
||||
}
|
||||
chunksize_buf[0] = '\0';
|
||||
chunksize_buf_index = 0;
|
||||
i++;
|
||||
} else {
|
||||
/* not finished to get chunksize */
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("chunksize = %u (%x)\n", chunksize, chunksize);
|
||||
#endif
|
||||
|
@ -226,12 +228,16 @@ 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)
|
||||
{
|
||||
content_buf = (char *)realloc((void *)content_buf,
|
||||
content_buf_used + bytestocopy);
|
||||
content_buf_len = content_buf_used + bytestocopy;
|
||||
if(content_length >= (int)(content_buf_used + bytestocopy)) {
|
||||
content_buf_len = content_length;
|
||||
} else {
|
||||
content_buf_len = content_buf_used + bytestocopy;
|
||||
}
|
||||
content_buf = (char *)realloc((void *)content_buf,
|
||||
content_buf_len);
|
||||
}
|
||||
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
|
||||
content_buf_used += bytestocopy;
|
||||
|
@ -241,17 +247,28 @@ getHTTPResponse(int s, int * size)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* not chunked */
|
||||
if(content_length > 0
|
||||
&& (int)(content_buf_used + n) > content_length) {
|
||||
/* skipping additional bytes */
|
||||
n = content_length - content_buf_used;
|
||||
}
|
||||
if(content_buf_used + n > content_buf_len)
|
||||
{
|
||||
content_buf = (char *)realloc((void *)content_buf,
|
||||
content_buf_used + n);
|
||||
content_buf_len = 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_len);
|
||||
}
|
||||
memcpy(content_buf + content_buf_used, buf, n);
|
||||
content_buf_used += n;
|
||||
}
|
||||
}
|
||||
if(content_length > 0 && content_buf_used >= content_length)
|
||||
/* use the Content-Length header value if available */
|
||||
if(content_length > 0 && (int)content_buf_used >= content_length)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("End of HTTP content\n");
|
||||
|
@ -274,29 +291,31 @@ end_of_stream:
|
|||
* do all the work.
|
||||
* Return NULL if something failed. */
|
||||
static void *
|
||||
miniwget3(const char * url, const char * host,
|
||||
unsigned short port, const char * path,
|
||||
int * size, char * addr_str, int addr_str_len, const char * httpversion)
|
||||
miniwget3(const char * host,
|
||||
unsigned short port, const char * path,
|
||||
int * size, char * addr_str, int addr_str_len,
|
||||
const char * httpversion, unsigned int scope_id)
|
||||
{
|
||||
char buf[2048];
|
||||
int s;
|
||||
int n;
|
||||
int len;
|
||||
int sent;
|
||||
void * content;
|
||||
|
||||
*size = 0;
|
||||
s = connecthostport(host, port);
|
||||
s = connecthostport(host, port, scope_id);
|
||||
if(s < 0)
|
||||
return NULL;
|
||||
|
||||
/* get address for caller ! */
|
||||
if(addr_str)
|
||||
{
|
||||
struct sockaddr saddr;
|
||||
struct sockaddr_storage saddr;
|
||||
socklen_t saddrlen;
|
||||
|
||||
saddrlen = sizeof(saddr);
|
||||
if(getsockname(s, &saddr, &saddrlen) < 0)
|
||||
if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
|
||||
{
|
||||
perror("getsockname");
|
||||
}
|
||||
|
@ -310,15 +329,28 @@ miniwget3(const char * url, const char * host,
|
|||
{
|
||||
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
|
||||
}*/
|
||||
/* the following code is only compatible with ip v4 addresses */
|
||||
strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
|
||||
#else
|
||||
/*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
|
||||
n = getnameinfo(&saddr, saddrlen,
|
||||
#if 0
|
||||
if(saddr.sa_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6,
|
||||
&(((struct sockaddr_in6 *)&saddr)->sin6_addr),
|
||||
addr_str, addr_str_len);
|
||||
} else {
|
||||
inet_ntop(AF_INET,
|
||||
&(((struct sockaddr_in *)&saddr)->sin_addr),
|
||||
addr_str, addr_str_len);
|
||||
}
|
||||
#endif
|
||||
/* getnameinfo return ip v6 address with the scope identifier
|
||||
* such as : 2a01:e35:8b2b:7330::%4281128194 */
|
||||
n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
|
||||
addr_str, addr_str_len,
|
||||
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));
|
||||
|
@ -355,30 +387,37 @@ miniwget3(const char * url, const char * host,
|
|||
sent += n;
|
||||
}
|
||||
}
|
||||
return getHTTPResponse(s, size);
|
||||
content = getHTTPResponse(s, size);
|
||||
closesocket(s);
|
||||
return content;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -390,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)
|
||||
|
@ -407,11 +449,75 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
|
|||
if( (url[0]!='h') || (url[1]!='t')
|
||||
||(url[2]!='t') || (url[3]!='p'))
|
||||
return 0;
|
||||
memset(hostname, 0, MAXHOSTNAMELEN + 1);
|
||||
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)
|
||||
{
|
||||
p2++;
|
||||
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
|
||||
if(*p2 == ':')
|
||||
{
|
||||
*port = 0;
|
||||
p2++;
|
||||
while( (*p2 >= '0') && (*p2 <= '9'))
|
||||
{
|
||||
*port *= 10;
|
||||
*port += (unsigned short)(*p2 - '0');
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*port = 80;
|
||||
}
|
||||
*path = p3;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
p2 = strchr(p1, ':');
|
||||
p3 = strchr(p1, '/');
|
||||
if(!p3)
|
||||
return 0;
|
||||
memset(hostname, 0, MAXHOSTNAMELEN + 1);
|
||||
if(!p2 || (p2>p3))
|
||||
{
|
||||
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
|
||||
|
@ -433,29 +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;
|
||||
return miniwget2(url, hostname, port, path, size, 0, 0);
|
||||
#ifdef DEBUG
|
||||
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
|
||||
hostname, port, path, scope_id);
|
||||
#endif
|
||||
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;
|
||||
return miniwget2(url, hostname, port, path, size, addr, addrlen);
|
||||
#ifdef DEBUG
|
||||
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
|
||||
hostname, port, path, scope_id);
|
||||
#endif
|
||||
return miniwget2(hostname, port, path, size, addr, addrlen, scope_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -142,19 +143,43 @@ static void parseelt(struct xmlparser * p)
|
|||
if (p->xml >= p->xmlend)
|
||||
return;
|
||||
while( IS_WHITE_SPACE(*p->xml) )
|
||||
{
|
||||
p->xml++;
|
||||
if (p->xml >= p->xmlend)
|
||||
return;
|
||||
}
|
||||
while(*p->xml!='<')
|
||||
{
|
||||
i++; p->xml++;
|
||||
if (p->xml >= p->xmlend)
|
||||
return;
|
||||
}
|
||||
if(i>0 && p->datafunc)
|
||||
p->datafunc(p->data, data, i);
|
||||
if(memcmp(p->xml, "<![CDATA[", 9) == 0)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(*p->xml == '/')
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/* $Id: upnpcommands.c,v 1.26 2010/06/09 10:59:09 nanard Exp $ */
|
||||
/* $Id: upnpcommands.c,v 1.40 2012/06/23 22:36:35 nanard Exp $ */
|
||||
/* Project : miniupnp
|
||||
* Author : Thomas Bernard
|
||||
* Copyright (c) 2005-2010 Thomas Bernard
|
||||
* Copyright (c) 2005-2012 Thomas Bernard
|
||||
* This software is subject to the conditions detailed in the
|
||||
* LICENCE file provided in this distribution.
|
||||
* */
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include <string.h>
|
||||
#include "upnpcommands.h"
|
||||
#include "miniupnpc.h"
|
||||
#include "portlistingparse.h"
|
||||
|
||||
static UNSIGNED_INTEGER
|
||||
my_atoui(const char * s)
|
||||
|
@ -24,15 +25,17 @@ UPNP_GetTotalBytesSent(const char * controlURL,
|
|||
const char * servicetype)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
unsigned int r = 0;
|
||||
char * p;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetTotalBytesSent", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
free(buffer); buffer = NULL;
|
||||
p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
|
||||
r = my_atoui(p);
|
||||
ClearNameValueList(&pdata);
|
||||
|
@ -46,15 +49,17 @@ UPNP_GetTotalBytesReceived(const char * controlURL,
|
|||
const char * servicetype)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
unsigned int r = 0;
|
||||
char * p;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetTotalBytesReceived", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
free(buffer); buffer = NULL;
|
||||
p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
|
||||
r = my_atoui(p);
|
||||
ClearNameValueList(&pdata);
|
||||
|
@ -68,15 +73,17 @@ UPNP_GetTotalPacketsSent(const char * controlURL,
|
|||
const char * servicetype)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
unsigned int r = 0;
|
||||
char * p;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetTotalPacketsSent", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
free(buffer); buffer = NULL;
|
||||
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
|
||||
r = my_atoui(p);
|
||||
ClearNameValueList(&pdata);
|
||||
|
@ -90,15 +97,17 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
|
|||
const char * servicetype)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
unsigned int r = 0;
|
||||
char * p;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetTotalPacketsReceived", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
free(buffer); buffer = NULL;
|
||||
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
|
||||
r = my_atoui(p);
|
||||
ClearNameValueList(&pdata);
|
||||
|
@ -110,13 +119,13 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
|
|||
LIBSPEC int
|
||||
UPNP_GetStatusInfo(const char * controlURL,
|
||||
const char * servicetype,
|
||||
char * status,
|
||||
char * status,
|
||||
unsigned int * uptime,
|
||||
char * lastconnerror)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
char * up;
|
||||
char * err;
|
||||
|
@ -125,11 +134,13 @@ UPNP_GetStatusInfo(const char * controlURL,
|
|||
if(!status && !uptime)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetStatusInfo", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
free(buffer); buffer = NULL;
|
||||
up = GetValueFromNameValueList(&pdata, "NewUptime");
|
||||
p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
|
||||
err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
|
||||
|
@ -176,19 +187,20 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
|
|||
char * connectionType)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
if(!connectionType)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetConnectionTypeInfo", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetConnectionTypeInfo", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
p = GetValueFromNameValueList(&pdata, "NewConnectionType");
|
||||
/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
|
||||
/* PossibleConnectionTypes will have several values.... */
|
||||
|
@ -209,18 +221,18 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
|
|||
|
||||
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
|
||||
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
|
||||
* One of the values can be null
|
||||
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
|
||||
* One of the values can be null
|
||||
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
|
||||
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
|
||||
LIBSPEC int
|
||||
UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
||||
const char * servicetype,
|
||||
unsigned int * bitrateDown,
|
||||
unsigned int* bitrateUp)
|
||||
unsigned int * bitrateUp)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
char * down;
|
||||
char * up;
|
||||
|
@ -230,19 +242,20 @@ UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
|||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
/* shouldn't we use GetCommonLinkProperties ? */
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetCommonLinkProperties", 0, buffer, &bufsize) < 0) {
|
||||
/*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetCommonLinkProperties", 0, &bufsize))) {
|
||||
/*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
|
||||
/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
|
||||
down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
|
||||
up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
|
||||
/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
|
||||
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
|
||||
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
|
||||
if(down && up)
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
|
||||
|
@ -272,7 +285,7 @@ UPNP_GetLinkLayerMaxBitRates(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
|
||||
*
|
||||
*
|
||||
* Return values :
|
||||
* 0 : SUCCESS
|
||||
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
|
||||
|
@ -286,19 +299,21 @@ UPNP_GetExternalIPAddress(const char * controlURL,
|
|||
char * extIpAdd)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
if(!extIpAdd || !controlURL || !servicetype)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetExternalIPAddress", 0, &bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
|
||||
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
|
||||
if(p) {
|
||||
|
@ -325,11 +340,12 @@ 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)
|
||||
{
|
||||
struct UPNParg * AddPortMappingArgs;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
int ret;
|
||||
|
@ -353,8 +369,10 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
|||
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
|
||||
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
|
||||
AddPortMappingArgs[7].elt = "NewLeaseDuration";
|
||||
AddPortMappingArgs[7].val = "0";
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize) < 0) {
|
||||
AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"AddPortMapping", AddPortMappingArgs,
|
||||
&bufsize))) {
|
||||
free(AddPortMappingArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
|
@ -362,6 +380,7 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
|||
/*buffer[bufsize] = '\0';*/
|
||||
/*puts(buffer);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal) {
|
||||
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
|
||||
|
@ -382,8 +401,8 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
|||
{
|
||||
/*struct NameValueParserData pdata;*/
|
||||
struct UPNParg * DeletePortMappingArgs;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
int ret;
|
||||
|
@ -398,14 +417,15 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
|||
DeletePortMappingArgs[1].val = extPort;
|
||||
DeletePortMappingArgs[2].elt = "NewProtocol";
|
||||
DeletePortMappingArgs[2].val = proto;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"DeletePortMapping",
|
||||
DeletePortMappingArgs, buffer, &bufsize) < 0 ) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"DeletePortMapping",
|
||||
DeletePortMappingArgs, &bufsize))) {
|
||||
free(DeletePortMappingArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal) {
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
@ -433,8 +453,8 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
|||
{
|
||||
struct NameValueParserData pdata;
|
||||
struct UPNParg * GetPortMappingArgs;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
int r = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
if(!index)
|
||||
|
@ -444,13 +464,15 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
|||
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
|
||||
GetPortMappingArgs[0].elt = "NewPortMappingIndex";
|
||||
GetPortMappingArgs[0].val = index;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetGenericPortMappingEntry",
|
||||
GetPortMappingArgs, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetGenericPortMappingEntry",
|
||||
GetPortMappingArgs, &bufsize))) {
|
||||
free(GetPortMappingArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
|
||||
if(p && rHost)
|
||||
{
|
||||
|
@ -517,17 +539,20 @@ UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
|
|||
unsigned int * numEntries)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char* p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetPortMappingNumberOfEntries", 0,
|
||||
&bufsize))) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
DisplayNameValueList(buffer, bufsize);
|
||||
#endif
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
|
||||
if(numEntries && p) {
|
||||
|
@ -555,12 +580,15 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
|||
const char * extPort,
|
||||
const char * proto,
|
||||
char * intClient,
|
||||
char * intPort)
|
||||
char * intPort,
|
||||
char * desc,
|
||||
char * enabled,
|
||||
char * leaseDuration)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
struct UPNParg * GetPortMappingArgs;
|
||||
char buffer[4096];
|
||||
int bufsize = 4096;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
|
@ -569,18 +597,20 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
|||
|
||||
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
||||
GetPortMappingArgs[0].elt = "NewRemoteHost";
|
||||
/* TODO : add remote host ? */
|
||||
GetPortMappingArgs[1].elt = "NewExternalPort";
|
||||
GetPortMappingArgs[1].val = extPort;
|
||||
GetPortMappingArgs[2].elt = "NewProtocol";
|
||||
GetPortMappingArgs[2].val = proto;
|
||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetSpecificPortMappingEntry",
|
||||
GetPortMappingArgs, buffer, &bufsize) < 0) {
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetSpecificPortMappingEntry",
|
||||
GetPortMappingArgs, &bufsize))) {
|
||||
free(GetPortMappingArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
||||
if(p) {
|
||||
|
@ -597,6 +627,25 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
|||
} else
|
||||
intPort[0] = '\0';
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewEnabled");
|
||||
if(p && enabled) {
|
||||
strncpy(enabled, p, 4);
|
||||
enabled[3] = '\0';
|
||||
}
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
|
||||
if(p && desc) {
|
||||
strncpy(desc, p, 80);
|
||||
desc[79] = '\0';
|
||||
}
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
|
||||
if(p && leaseDuration)
|
||||
{
|
||||
strncpy(leaseDuration, p, 16);
|
||||
leaseDuration[15] = '\0';
|
||||
}
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(p) {
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
@ -608,4 +657,441 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* UPNP_GetListOfPortMappings()
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
struct UPNParg * GetListOfPortMappingsArgs;
|
||||
const char * p;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
if(!startPort || !endPort || !protocol)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
|
||||
GetListOfPortMappingsArgs[0].elt = "NewStartPort";
|
||||
GetListOfPortMappingsArgs[0].val = startPort;
|
||||
GetListOfPortMappingsArgs[1].elt = "NewEndPort";
|
||||
GetListOfPortMappingsArgs[1].val = endPort;
|
||||
GetListOfPortMappingsArgs[2].elt = "NewProtocol";
|
||||
GetListOfPortMappingsArgs[2].val = protocol;
|
||||
GetListOfPortMappingsArgs[3].elt = "NewManage";
|
||||
GetListOfPortMappingsArgs[3].val = "1";
|
||||
GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
|
||||
GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
|
||||
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetListOfPortMappings",
|
||||
GetListOfPortMappingsArgs, &bufsize))) {
|
||||
free(GetListOfPortMappingsArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
free(GetListOfPortMappingsArgs);
|
||||
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
|
||||
/*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
|
||||
/*if(p) {
|
||||
printf("NewPortListing : %s\n", p);
|
||||
}*/
|
||||
/*printf("NewPortListing(%d chars) : %s\n",
|
||||
pdata.portListingLength, pdata.portListing);*/
|
||||
if(pdata.portListing)
|
||||
{
|
||||
/*struct PortMapping * pm;
|
||||
int i = 0;*/
|
||||
ParsePortListing(pdata.portListing, pdata.portListingLength,
|
||||
data);
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
/*
|
||||
for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
|
||||
{
|
||||
printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
|
||||
i, pm->protocol, pm->externalPort, pm->internalClient,
|
||||
pm->internalPort,
|
||||
pm->description, pm->remoteHost);
|
||||
i++;
|
||||
}
|
||||
*/
|
||||
/*FreePortListing(&data);*/
|
||||
}
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(p) {
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(p, "%d", &ret);
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
|
||||
/*printf("%.*s", bufsize, buffer);*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
|
||||
LIBSPEC int
|
||||
UPNP_GetFirewallStatus(const char * controlURL,
|
||||
const char * servicetype,
|
||||
int * firewallEnabled,
|
||||
int * inboundPinholeAllowed)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * fe, *ipa, *p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
if(!firewallEnabled && !inboundPinholeAllowed)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetFirewallStatus", 0, &bufsize);
|
||||
if(!buffer) {
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
|
||||
ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
|
||||
if(ipa && fe)
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
if(fe)
|
||||
*firewallEnabled = my_atoui(fe);
|
||||
/*else
|
||||
*firewallEnabled = 0;*/
|
||||
if(ipa)
|
||||
*inboundPinholeAllowed = my_atoui(ipa);
|
||||
/*else
|
||||
*inboundPinholeAllowed = 0;*/
|
||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(p)
|
||||
{
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(p, "%d", &ret);
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct UPNParg * GetOutboundPinholeTimeoutArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
char * p;
|
||||
int ret;
|
||||
|
||||
if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
|
||||
GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
|
||||
GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
|
||||
GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
|
||||
GetOutboundPinholeTimeoutArgs[1].val = remotePort;
|
||||
GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
|
||||
GetOutboundPinholeTimeoutArgs[2].val = proto;
|
||||
GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
|
||||
GetOutboundPinholeTimeoutArgs[3].val = intPort;
|
||||
GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
|
||||
GetOutboundPinholeTimeoutArgs[4].val = intClient;
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
|
||||
if(!buffer)
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal)
|
||||
{
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(resVal, "%d", &ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
|
||||
if(p)
|
||||
*opTimeout = my_atoui(p);
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
free(GetOutboundPinholeTimeoutArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct UPNParg * AddPinholeArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
char * p;
|
||||
int ret;
|
||||
|
||||
if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
|
||||
/* RemoteHost can be wilcarded */
|
||||
if(strncmp(remoteHost, "empty", 5)==0)
|
||||
{
|
||||
AddPinholeArgs[0].elt = "RemoteHost";
|
||||
AddPinholeArgs[0].val = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPinholeArgs[0].elt = "RemoteHost";
|
||||
AddPinholeArgs[0].val = remoteHost;
|
||||
}
|
||||
AddPinholeArgs[1].elt = "RemotePort";
|
||||
AddPinholeArgs[1].val = remotePort;
|
||||
AddPinholeArgs[2].elt = "Protocol";
|
||||
AddPinholeArgs[2].val = proto;
|
||||
AddPinholeArgs[3].elt = "InternalPort";
|
||||
AddPinholeArgs[3].val = intPort;
|
||||
if(strncmp(intClient, "empty", 5)==0)
|
||||
{
|
||||
AddPinholeArgs[4].elt = "InternalClient";
|
||||
AddPinholeArgs[4].val = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPinholeArgs[4].elt = "InternalClient";
|
||||
AddPinholeArgs[4].val = intClient;
|
||||
}
|
||||
AddPinholeArgs[5].elt = "LeaseTime";
|
||||
AddPinholeArgs[5].val = leaseTime;
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"AddPinhole", AddPinholeArgs, &bufsize);
|
||||
if(!buffer)
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
p = GetValueFromNameValueList(&pdata, "UniqueID");
|
||||
if(p)
|
||||
{
|
||||
strncpy(uniqueID, p, 8);
|
||||
uniqueID[7] = '\0';
|
||||
}
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal)
|
||||
{
|
||||
/*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(resVal, "%d", &ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
free(AddPinholeArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
|
||||
const char * uniqueID,
|
||||
const char * leaseTime)
|
||||
{
|
||||
struct UPNParg * UpdatePinholeArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
int ret;
|
||||
|
||||
if(!uniqueID || !leaseTime)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
|
||||
UpdatePinholeArgs[0].elt = "UniqueID";
|
||||
UpdatePinholeArgs[0].val = uniqueID;
|
||||
UpdatePinholeArgs[1].elt = "NewLeaseTime";
|
||||
UpdatePinholeArgs[1].val = leaseTime;
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"UpdatePinhole", UpdatePinholeArgs, &bufsize);
|
||||
if(!buffer)
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal)
|
||||
{
|
||||
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(resVal, "%d", &ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
free(UpdatePinholeArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
|
||||
{
|
||||
/*struct NameValueParserData pdata;*/
|
||||
struct UPNParg * DeletePinholeArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
int ret;
|
||||
|
||||
if(!uniqueID)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
|
||||
DeletePinholeArgs[0].elt = "UniqueID";
|
||||
DeletePinholeArgs[0].val = uniqueID;
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"DeletePinhole", DeletePinholeArgs, &bufsize);
|
||||
if(!buffer)
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
/*DisplayNameValueList(buffer, bufsize);*/
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal)
|
||||
{
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(resVal, "%d", &ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
free(DeletePinholeArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
|
||||
const char * uniqueID, int * isWorking)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
struct UPNParg * CheckPinholeWorkingArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
if(!uniqueID)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
|
||||
CheckPinholeWorkingArgs[0].elt = "UniqueID";
|
||||
CheckPinholeWorkingArgs[0].val = uniqueID;
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
|
||||
if(!buffer)
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "IsWorking");
|
||||
if(p)
|
||||
{
|
||||
*isWorking=my_atoui(p);
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
}
|
||||
else
|
||||
*isWorking = 0;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(p)
|
||||
{
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(p, "%d", &ret);
|
||||
}
|
||||
|
||||
ClearNameValueList(&pdata);
|
||||
free(CheckPinholeWorkingArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
|
||||
const char * uniqueID, int * packets)
|
||||
{
|
||||
struct NameValueParserData pdata;
|
||||
struct UPNParg * GetPinholePacketsArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
char * p;
|
||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
|
||||
if(!uniqueID)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
|
||||
GetPinholePacketsArgs[0].elt = "UniqueID";
|
||||
GetPinholePacketsArgs[0].val = uniqueID;
|
||||
buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"GetPinholePackets", GetPinholePacketsArgs, &bufsize);
|
||||
if(!buffer)
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "PinholePackets");
|
||||
if(p)
|
||||
{
|
||||
*packets=my_atoui(p);
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
}
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(p)
|
||||
{
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(p, "%d", &ret);
|
||||
}
|
||||
|
||||
ClearNameValueList(&pdata);
|
||||
free(GetPinholePacketsArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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().
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -9,6 +9,7 @@
|
|||
#include <string.h>
|
||||
#include "upnperrors.h"
|
||||
#include "upnpcommands.h"
|
||||
#include "miniupnpc.h"
|
||||
|
||||
const char * strupnperror(int err)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -60,7 +97,8 @@ const char * strupnperror(int err)
|
|||
s = "ExternalPortOnlySupportsWildcard";
|
||||
break;
|
||||
default:
|
||||
s = NULL;
|
||||
s = "UnknownError";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
|
@ -58,6 +108,12 @@ 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);
|
||||
|
@ -65,7 +121,7 @@ ClearNameValueList(struct NameValueParserData * pdata)
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
||||
const char * Name)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
@ -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() */
|
||||
|
@ -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
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
2013-xx-xx: Version 3.1.1
|
||||
* General:
|
||||
* Change: Simplify build process by getting rid of bison/flex dependencies (commit:d13bc0de7dd0588351af24dc45d55110d0eed6e8)
|
||||
* Change: Filter out bad maps (commit:acfe83cdf6f44660276ba73931e2cebdc8a250ac)
|
||||
* Change: Also show in the bottom menu, if allies are researching the same as us (commit:b6b6265e4e430486ea44a200bce870b115dfc37f)
|
||||
* Change: Keep showing allied research even while facilities are upgraded (commit:423e358b6715c12dda70ff5f6f2bd0348c09f699)
|
||||
* Change: Retreat buttons now should health bar colours (commit:4e2f4bbf3cd5e03e58b9b67fcf370bff088e6d91)
|
||||
* Change: Retreat buttons now show health bar colours (commit:4e2f4bbf3cd5e03e58b9b67fcf370bff088e6d91)
|
||||
* Fix: Bug that made droids produced by scripts get human player's upgrades (commit:8149dc94c0b61117982281cdaf2aac1bec2525e9)
|
||||
* Fix: Backwards terrain shadows (commit:85ecd9a3937e7843d9eb4798572651f950bd7555)
|
||||
* Fix: Mod loading bug (commit:87cade1a684f3da0572f13e92539100f35b4f6fe, ticket:3567)
|
||||
|
@ -25,7 +24,9 @@
|
|||
* Fix: Add parameter checking for buildings that do not exist (commit:e38de7b64242a547acd77c7775dbfae10c74ca3d)
|
||||
* Maps:
|
||||
* Fix: Remove lop-sided oil barrels from 4c-pyramidal (commit:6092fe1194529f0c7fe023d9c98973e44f9f9f24)
|
||||
* Add: Gamma (3p) and Melting (6p) by NoQ (commit:b8bdf44737e1d9423c2581b1377cf1be9c4a3666)
|
||||
* Build system:
|
||||
* Change: Simplify build process by getting rid of bison/flex dependencies (commit:d13bc0de7dd0588351af24dc45d55110d0eed6e8)
|
||||
* Fix: Building on OpenBSD (commit:9b9383500fb4c1dd5270a68e3490dc358e2da55f, ticket:3917, commit:47a6d6d4684b993d15e378f6d0877fa043b26ca0, ticket:3845)
|
||||
|
||||
2012-12-09: Version 3.1.0
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
@ -934,7 +935,6 @@ static bool NETrecvGAMESTRUCT(GAMESTRUCT* ourgamestruct)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static int upnp_init(void *asdf)
|
||||
{
|
||||
struct UPNPDev *devlist;
|
||||
|
@ -942,14 +942,14 @@ static int upnp_init(void *asdf)
|
|||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1108,11 +1138,6 @@ int NETshutdown(void)
|
|||
NETdeleteQueue();
|
||||
SOCKETshutdown();
|
||||
|
||||
if (NetPlay.bComms && NetPlay.isUPNP)
|
||||
{
|
||||
NETremRedirects();
|
||||
}
|
||||
|
||||
// Reset net usage statistics.
|
||||
nStats = nZeroStats;
|
||||
nStatsLastSec = nZeroStats;
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
@ -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>
|
|
@ -537,11 +537,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);
|
||||
|
|
|
@ -3780,9 +3780,22 @@ bool startMultiOptions(bool bReenter)
|
|||
}
|
||||
else
|
||||
{
|
||||
char buf[512] = {'\0'};
|
||||
addPlayerBox(false); // Players
|
||||
addGameOptions();
|
||||
addChatBox();
|
||||
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..
|
||||
|
|
Loading…
Reference in New Issue