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.
|
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:
|
2010/12/21:
|
||||||
use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
|
use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
|
||||||
|
|
||||||
|
@ -155,7 +354,7 @@ VERSION 1.2 :
|
||||||
small modif to make Clang happy :)
|
small modif to make Clang happy :)
|
||||||
|
|
||||||
2008/07/17:
|
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:
|
2008/07/14:
|
||||||
include declspec.h in installation (to /usr/include/miniupnpc)
|
include declspec.h in installation (to /usr/include/miniupnpc)
|
||||||
|
@ -177,7 +376,7 @@ VERSION 1.1 :
|
||||||
improved python module error/exception reporting.
|
improved python module error/exception reporting.
|
||||||
|
|
||||||
2008/04/23:
|
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
|
Linksys WAG200G
|
||||||
Added testigddescparse
|
Added testigddescparse
|
||||||
updated python module
|
updated python module
|
||||||
|
@ -200,7 +399,7 @@ VERSION 1.0 :
|
||||||
improved make install :)
|
improved make install :)
|
||||||
|
|
||||||
2007/12/22:
|
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.
|
used to translate UPnP error codes to string.
|
||||||
|
|
||||||
2007/12/19:
|
2007/12/19:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Copyright (c) 2005-2009, Thomas BERNARD
|
MiniUPnPc
|
||||||
|
Copyright (c) 2005-2011, Thomas BERNARD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -18,8 +18,11 @@ noinst_HEADERS = \
|
||||||
minissdpc.h \
|
minissdpc.h \
|
||||||
miniupnpc.h \
|
miniupnpc.h \
|
||||||
miniupnpcstrings.h \
|
miniupnpcstrings.h \
|
||||||
|
miniupnpctypes.h \
|
||||||
miniwget.h \
|
miniwget.h \
|
||||||
minixml.h \
|
minixml.h \
|
||||||
|
portlistingparse.h \
|
||||||
|
receivedata.h \
|
||||||
upnpcommands.h \
|
upnpcommands.h \
|
||||||
upnperrors.h \
|
upnperrors.h \
|
||||||
upnpreplyparse.h
|
upnpreplyparse.h
|
||||||
|
@ -32,6 +35,8 @@ libminiupnpc_a_SOURCES = \
|
||||||
miniupnpc.c \
|
miniupnpc.c \
|
||||||
miniwget.c \
|
miniwget.c \
|
||||||
minixml.c \
|
minixml.c \
|
||||||
|
portlistingparse.c \
|
||||||
|
receivedata.c \
|
||||||
upnpcommands.c \
|
upnpcommands.c \
|
||||||
upnperrors.c \
|
upnperrors.c \
|
||||||
upnpreplyparse.c
|
upnpreplyparse.c
|
||||||
|
|
|
@ -1,28 +1,35 @@
|
||||||
Project: miniupnp
|
Project: miniupnp
|
||||||
Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
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
|
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
|
This software is subject to the conditions detailed in the
|
||||||
LICENSE file provided within this distribution.
|
LICENSE file provided within this distribution.
|
||||||
|
|
||||||
|
|
||||||
For the comfort of Win32 users, bsdqueue.h is included in the distribution.
|
For the comfort of Win32 users, bsdqueue.h is included in the distribution.
|
||||||
Its licence is included in the header of the file.
|
Its licence is included in the header of the file.
|
||||||
bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system.
|
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).
|
To compile, simply run 'gmake' (could be 'make' on your system).
|
||||||
Under win32, to compile with MinGW, type "mingw32make.bat".
|
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,
|
The compilation is known to work under linux, FreeBSD,
|
||||||
OpenBSD, MacOS X, AmigaOS and cygwin.
|
OpenBSD, MacOS X, AmigaOS and cygwin.
|
||||||
The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
|
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 :
|
To install the library and headers on the system use :
|
||||||
> su
|
> su
|
||||||
> make install
|
> make install
|
||||||
> exit
|
> exit
|
||||||
|
|
||||||
alternatively, to install in a specific location, use :
|
alternatively, to install into a specific location, use :
|
||||||
> INSTALLPREFIX=/usr/local make install
|
> INSTALLPREFIX=/usr/local make install
|
||||||
|
|
||||||
upnpc.c is a sample client using the libminiupnpc.
|
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.
|
Discovery process is speeded up when MiniSSDPd is running on the machine.
|
||||||
|
|
||||||
|
|
||||||
* Python module *
|
* 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'.
|
and install it with 'make installpythonmodule'.
|
||||||
setup.py (and setupmingw32.py) are included in the distribution.
|
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
|
If you are using libminiupnpc in your application, please
|
||||||
send me an email !
|
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_
|
#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.
|
* lists, simple queues, tail queues, and circular queues.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *slh_first; /* first element */ \
|
struct type *slh_first; /* first element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SLIST_HEAD_INITIALIZER(head) \
|
#define SLIST_HEAD_INITIALIZER(head) \
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ struct name { \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *sle_next; /* next element */ \
|
struct type *sle_next; /* next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Singly-linked List access methods.
|
* Singly-linked List access methods.
|
||||||
*/
|
*/
|
||||||
|
@ -322,8 +322,8 @@ struct { \
|
||||||
struct type **tqe_prev; /* address of previous next element */ \
|
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_FIRST(head) ((head)->tqh_first)
|
||||||
#define TAILQ_END(head) NULL
|
#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_FIRST(head) ((head)->cqh_first)
|
||||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
#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
|
/* Project : miniupnp
|
||||||
* Author : Thomas BERNARD
|
* 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
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENCE file. */
|
* provided LICENCE file. */
|
||||||
#ifndef __CODELENGTH_H__
|
#ifndef CODELENGTH_H_INCLUDED
|
||||||
#define __CODELENGTH_H__
|
#define CODELENGTH_H_INCLUDED
|
||||||
|
|
||||||
/* Encode length by using 7bit per Byte :
|
/* Encode length by using 7bit per Byte :
|
||||||
* Most significant bit of each byte specifies that the
|
* Most significant bit of each byte specifies that the
|
||||||
* following byte is part of the code */
|
* following byte is part of the code */
|
||||||
#define DECODELENGTH(n, p) n = 0; \
|
#define DECODELENGTH(n, p) n = 0; \
|
||||||
do { n = (n << 7) | (*p & 0x7f); } \
|
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; \
|
#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
|
||||||
if(n>=2097152) *(p++) = (n >> 21) | 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
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2010 Thomas Bernard
|
* Copyright (c) 2010-2013 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
|
@ -13,18 +13,22 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define herror
|
#define herror
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
#else /* #ifdef WIN32 */
|
#else /* #ifdef _WIN32 */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
||||||
* during the connect() call */
|
* during the connect() call */
|
||||||
#define MINIUPNPC_IGNORE_EINTR
|
#define MINIUPNPC_IGNORE_EINTR
|
||||||
|
@ -32,10 +36,10 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif /* #ifndef USE_GETHOSTBYNAME */
|
#endif /* #ifndef USE_GETHOSTBYNAME */
|
||||||
#endif /* #else WIN32 */
|
#endif /* #else _WIN32 */
|
||||||
|
|
||||||
/* definition of PRINT_SOCKET_ERROR */
|
/* definition of PRINT_SOCKET_ERROR */
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
||||||
#else
|
#else
|
||||||
#define PRINT_SOCKET_ERROR(x) perror(x)
|
#define PRINT_SOCKET_ERROR(x) perror(x)
|
||||||
|
@ -47,16 +51,22 @@
|
||||||
|
|
||||||
#include "connecthostport.h"
|
#include "connecthostport.h"
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
/* connecthostport()
|
/* connecthostport()
|
||||||
* return a socket connected (TCP) to the host and port
|
* return a socket connected (TCP) to the host and port
|
||||||
* or -1 in case of error */
|
* 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;
|
int s, n;
|
||||||
#ifdef USE_GETHOSTBYNAME
|
#ifdef USE_GETHOSTBYNAME
|
||||||
struct sockaddr_in dest;
|
struct sockaddr_in dest;
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
#else /* #ifdef USE_GETHOSTBYNAME */
|
#else /* #ifdef USE_GETHOSTBYNAME */
|
||||||
|
char tmp_host[MAXHOSTNAMELEN+1];
|
||||||
char port_str[8];
|
char port_str[8];
|
||||||
struct addrinfo *ai, *p;
|
struct addrinfo *ai, *p;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
|
@ -64,7 +74,7 @@ int connecthostport(const char * host, unsigned short port)
|
||||||
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
|
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
|
||||||
|
|
||||||
#ifdef USE_GETHOSTBYNAME
|
#ifdef USE_GETHOSTBYNAME
|
||||||
hp = gethostbyname(host);
|
hp = gethostbyname(host);
|
||||||
if(hp == NULL)
|
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_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
|
||||||
/* hints.ai_protocol = IPPROTO_TCP; */
|
/* hints.ai_protocol = IPPROTO_TCP; */
|
||||||
snprintf(port_str, sizeof(port_str), "%hu", port);
|
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)
|
if(n != 0)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
fprintf(stderr, "getaddrinfo() error : %d\n", n);
|
fprintf(stderr, "getaddrinfo() error : %d\n", n);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
|
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);
|
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
continue;
|
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
|
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||||
/* setting a 3 seconds timeout for the connect() call */
|
/* setting a 3 seconds timeout for the connect() call */
|
||||||
timeout.tv_sec = 3;
|
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
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2010 Thomas Bernard
|
* Copyright (c) 2010-2012 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef __CONNECTHOSTPORT_H__
|
#ifndef CONNECTHOSTPORT_H_INCLUDED
|
||||||
#define __CONNECTHOSTPORT_H__
|
#define CONNECTHOSTPORT_H_INCLUDED
|
||||||
|
|
||||||
/* connecthostport()
|
/* connecthostport()
|
||||||
* return a socket connected (TCP) to the host and port
|
* return a socket connected (TCP) to the host and port
|
||||||
* or -1 in case of error */
|
* 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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __DECLSPEC_H__
|
#ifndef DECLSPEC_H_INCLUDED
|
||||||
#define __DECLSPEC_H__
|
#define DECLSPEC_H_INCLUDED
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(STATICLIB)
|
#if defined(_WIN32) && !defined(STATICLIB)
|
||||||
#ifdef MINIUPNP_EXPORTS
|
#ifdef MINIUPNP_EXPORTS
|
||||||
#define LIBSPEC __declspec(dllexport)
|
#define LIBSPEC __declspec(dllexport)
|
||||||
#else
|
#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
|
/* Project : miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
|
@ -46,6 +46,9 @@ void IGDendelt(void * d, const char * name, int l)
|
||||||
if(0==strcmp(datas->tmp.servicetype,
|
if(0==strcmp(datas->tmp.servicetype,
|
||||||
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
|
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
|
||||||
memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
|
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,
|
} else if(0==strcmp(datas->tmp.servicetype,
|
||||||
"urn:schemas-upnp-org:service:WANIPConnection:1")
|
"urn:schemas-upnp-org:service:WANIPConnection:1")
|
||||||
|| 0==strcmp(datas->tmp.servicetype,
|
|| 0==strcmp(datas->tmp.servicetype,
|
||||||
|
@ -69,6 +72,8 @@ void IGDdata(void * d, const char * data, int l)
|
||||||
datas->level, datas->cureltname, l, data); */
|
datas->level, datas->cureltname, l, data); */
|
||||||
if( !strcmp(datas->cureltname, "URLBase") )
|
if( !strcmp(datas->cureltname, "URLBase") )
|
||||||
dstmember = datas->urlbase;
|
dstmember = datas->urlbase;
|
||||||
|
else if( !strcmp(datas->cureltname, "presentationURL") )
|
||||||
|
dstmember = datas->presentationurl;
|
||||||
else if( !strcmp(datas->cureltname, "serviceType") )
|
else if( !strcmp(datas->cureltname, "serviceType") )
|
||||||
dstmember = datas->tmp.servicetype;
|
dstmember = datas->tmp.servicetype;
|
||||||
else if( !strcmp(datas->cureltname, "controlURL") )
|
else if( !strcmp(datas->cureltname, "controlURL") )
|
||||||
|
@ -109,6 +114,12 @@ void printIGD(struct IGDdatas * d)
|
||||||
printf(" controlURL = '%s'\n", d->second.controlurl);
|
printf(" controlURL = '%s'\n", d->second.controlurl);
|
||||||
printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
|
printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
|
||||||
printf(" SCPDURL = '%s'\n", d->second.scpdurl);
|
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
|
/* Project : miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
|
@ -6,8 +6,8 @@
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution.
|
* LICENCE file provided in this distribution.
|
||||||
* */
|
* */
|
||||||
#ifndef __IGD_DESC_PARSE_H__
|
#ifndef IGD_DESC_PARSE_H_INCLUDED
|
||||||
#define __IGD_DESC_PARSE_H__
|
#define IGD_DESC_PARSE_H_INCLUDED
|
||||||
|
|
||||||
/* Structure to store the result of the parsing of UPnP
|
/* Structure to store the result of the parsing of UPnP
|
||||||
* descriptions of Internet Gateway Devices */
|
* descriptions of Internet Gateway Devices */
|
||||||
|
@ -23,6 +23,7 @@ struct IGDdatas_service {
|
||||||
struct IGDdatas {
|
struct IGDdatas {
|
||||||
char cureltname[MINIUPNPC_URL_MAXSIZE];
|
char cureltname[MINIUPNPC_URL_MAXSIZE];
|
||||||
char urlbase[MINIUPNPC_URL_MAXSIZE];
|
char urlbase[MINIUPNPC_URL_MAXSIZE];
|
||||||
|
char presentationurl[MINIUPNPC_URL_MAXSIZE];
|
||||||
int level;
|
int level;
|
||||||
/*int state;*/
|
/*int state;*/
|
||||||
/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
|
/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
|
||||||
|
@ -32,6 +33,8 @@ struct IGDdatas {
|
||||||
struct IGDdatas_service first;
|
struct IGDdatas_service first;
|
||||||
/* if both WANIPConnection and WANPPPConnection are present */
|
/* if both WANIPConnection and WANPPPConnection are present */
|
||||||
struct IGDdatas_service second;
|
struct IGDdatas_service second;
|
||||||
|
/* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
|
||||||
|
struct IGDdatas_service IPv6FC;
|
||||||
/* tmp */
|
/* tmp */
|
||||||
struct IGDdatas_service 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
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution.
|
* LICENCE file provided in this distribution.
|
||||||
*
|
*
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
/* only for malloc */
|
/* only for malloc */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
||||||
#else
|
#else
|
||||||
#define PRINT_SOCKET_ERROR(x) perror(x)
|
#define PRINT_SOCKET_ERROR(x) perror(x)
|
||||||
|
@ -57,7 +57,7 @@ httpWrite(int fd, const char * body, int bodysize,
|
||||||
/* disable send on the socket */
|
/* disable send on the socket */
|
||||||
/* draytek routers dont seems to like that... */
|
/* draytek routers dont seems to like that... */
|
||||||
#if 0
|
#if 0
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
if(shutdown(fd, SD_SEND)<0) {
|
if(shutdown(fd, SD_SEND)<0) {
|
||||||
#else
|
#else
|
||||||
if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/
|
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",
|
printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
|
||||||
url, httpversion, host, portstr);
|
url, httpversion, host, portstr);
|
||||||
printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
|
printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
|
||||||
/*printf("%s", headerbuf);*/
|
printf("Headers :\n%s", headerbuf);
|
||||||
|
printf("Body :\n%s\n", body);
|
||||||
#endif
|
#endif
|
||||||
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
|
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
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005 Thomas Bernard
|
* Copyright (c) 2005 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
#ifndef __MINISOAP_H__
|
#ifndef MINISOAP_H_INCLUDED
|
||||||
#define __MINISOAP_H__
|
#define MINISOAP_H_INCLUDED
|
||||||
|
|
||||||
/*int httpWrite(int, const char *, int, const char *);*/
|
/*int httpWrite(int, const char *, int, const char *);*/
|
||||||
int soapPostSubmit(int, const char *, const char *, unsigned short,
|
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
|
/* Project : miniupnp
|
||||||
|
* Web : http://miniupnp.free.fr/
|
||||||
* Author : Thomas BERNARD
|
* 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
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENCE file. */
|
* provided LICENCE file. */
|
||||||
/*#include <syslog.h>*/
|
/*#include <syslog.h>*/
|
||||||
#include <lib/framework/types.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__)
|
#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
@ -41,6 +41,10 @@ struct sockaddr_un {
|
||||||
|
|
||||||
#include "codelength.h"
|
#include "codelength.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct UPNPDev *
|
struct UPNPDev *
|
||||||
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +124,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
||||||
p += stsize;
|
p += stsize;
|
||||||
tmp->buffer[urlsize+1+stsize] = '\0';
|
tmp->buffer[urlsize+1+stsize] = '\0';
|
||||||
devlist = tmp;
|
devlist = tmp;
|
||||||
/* added for compatibility with recent versions of MiniSSDPd
|
/* added for compatibility with recent versions of MiniSSDPd
|
||||||
* >= 2007/12/19 */
|
* >= 2007/12/19 */
|
||||||
DECODELENGTH(usnsize, p);
|
DECODELENGTH(usnsize, p);
|
||||||
p += usnsize;
|
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
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2005-2007 Thomas Bernard
|
* Copyright (c) 2005-2007 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef __MINISSDPC_H__
|
#ifndef MINISSDPC_H_INCLUDED
|
||||||
#define __MINISSDPC_H__
|
#define MINISSDPC_H_INCLUDED
|
||||||
|
|
||||||
struct UPNPDev *
|
struct UPNPDev *
|
||||||
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath);
|
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
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2005-2006 Thomas Bernard
|
* Copyright (c) 2005-2012 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef __MINIUPNPC_H__
|
#ifndef MINIUPNPC_H_INCLUDED
|
||||||
#define __MINIUPNPC_H__
|
#define MINIUPNPC_H_INCLUDED
|
||||||
|
|
||||||
#include "declspec.h"
|
#include "declspec.h"
|
||||||
#include "igd_desc_parse.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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,14 +28,16 @@ extern "C" {
|
||||||
/* Structures definitions : */
|
/* Structures definitions : */
|
||||||
struct UPNParg { const char * elt; const char * val; };
|
struct UPNParg { const char * elt; const char * val; };
|
||||||
|
|
||||||
int simpleUPnPcommand(int, const char *, const char *,
|
char *
|
||||||
const char *, struct UPNParg *,
|
simpleUPnPcommand(int, const char *, const char *,
|
||||||
char *, int *);
|
const char *, struct UPNParg *,
|
||||||
|
int *);
|
||||||
|
|
||||||
struct UPNPDev {
|
struct UPNPDev {
|
||||||
struct UPNPDev * pNext;
|
struct UPNPDev * pNext;
|
||||||
char * descURL;
|
char * descURL;
|
||||||
char * st;
|
char * st;
|
||||||
|
unsigned int scope_id;
|
||||||
char buffer[2];
|
char buffer[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,8 +54,11 @@ struct UPNPDev {
|
||||||
* multicast interface for sending SSDP discover packets.
|
* multicast interface for sending SSDP discover packets.
|
||||||
* If sameport is not null, SSDP packets will be sent from the source port
|
* 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. */
|
* 1900 (same as destination port) otherwise system assign a source port. */
|
||||||
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
LIBSPEC struct UPNPDev *
|
||||||
const char * minissdpdsock, int sameport);
|
upnpDiscover(int delay, const char * multicastif,
|
||||||
|
const char * minissdpdsock, int sameport,
|
||||||
|
int ipv6,
|
||||||
|
int * error);
|
||||||
/* freeUPNPDevlist()
|
/* freeUPNPDevlist()
|
||||||
* free list returned by upnpDiscover() */
|
* free list returned by upnpDiscover() */
|
||||||
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
|
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
|
||||||
|
@ -57,11 +72,14 @@ LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
|
||||||
* controlURL: controlURL of the WANIPConnection
|
* controlURL: controlURL of the WANIPConnection
|
||||||
* ipcondescURL: url of the description of the WANIPConnection
|
* ipcondescURL: url of the description of the WANIPConnection
|
||||||
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
|
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
|
||||||
|
* controlURL_6FC: controlURL of the WANIPv6FirewallControl
|
||||||
*/
|
*/
|
||||||
struct UPNPUrls {
|
struct UPNPUrls {
|
||||||
char * controlURL;
|
char * controlURL;
|
||||||
char * ipcondescURL;
|
char * ipcondescURL;
|
||||||
char * controlURL_CIF;
|
char * controlURL_CIF;
|
||||||
|
char * controlURL_6FC;
|
||||||
|
char * rootdescURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* UPNP_GetValidIGD() :
|
/* UPNP_GetValidIGD() :
|
||||||
|
@ -93,14 +111,12 @@ UPNP_GetIGDFromUrl(const char * rootdescurl,
|
||||||
struct IGDdatas * data,
|
struct IGDdatas * data,
|
||||||
char * lanaddr, int lanaddrlen);
|
char * lanaddr, int lanaddrlen);
|
||||||
|
|
||||||
LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);
|
LIBSPEC void
|
||||||
|
GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
|
||||||
|
const char *, unsigned int);
|
||||||
|
|
||||||
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
|
LIBSPEC void
|
||||||
|
FreeUPNPUrls(struct UPNPUrls *);
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* return 0 or 1 */
|
/* return 0 or 1 */
|
||||||
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
|
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 $ */
|
#ifndef MINIUPNPCSTRINGS_H_INCLUDED
|
||||||
/* Project: miniupnp
|
#define MINIUPNPCSTRINGS_H_INCLUDED
|
||||||
* 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__
|
|
||||||
|
|
||||||
#include "lib/framework/wzglobal.h"
|
|
||||||
|
|
||||||
#if defined(WZ_OS_WIN32)
|
|
||||||
#define OS_STRING "Windows"
|
#define OS_STRING "Windows"
|
||||||
#elif defined (WZ_OS_MAC)
|
#define MINIUPNPC_VERSION_STRING "1.7"
|
||||||
#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"
|
|
||||||
|
|
||||||
#endif
|
#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
|
/* Project : miniupnp
|
||||||
|
* Website : http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "miniupnpc.h"
|
#ifdef _WIN32
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
@ -18,12 +18,14 @@
|
||||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
|
#ifndef strncasecmp
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
#define strncasecmp _memicmp
|
#define strncasecmp _memicmp
|
||||||
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
#define strncasecmp memicmp
|
#define strncasecmp memicmp
|
||||||
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
#else /* #ifdef WIN32 */
|
#endif /* #ifndef strncasecmp */
|
||||||
|
#else /* #ifdef _WIN32 */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#if defined(__amigaos__) && !defined(__amigaos4__)
|
#if defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
|
@ -32,13 +34,15 @@
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
|
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
||||||
* during the connect() call */
|
* during the connect() call */
|
||||||
#define MINIUPNPC_IGNORE_EINTR
|
#define MINIUPNPC_IGNORE_EINTR
|
||||||
#endif /* #else WIN32 */
|
#endif /* #else _WIN32 */
|
||||||
#if defined(__sun) || defined(sun)
|
#if defined(__sun) || defined(sun)
|
||||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,35 +50,46 @@
|
||||||
#include "miniupnpcstrings.h"
|
#include "miniupnpcstrings.h"
|
||||||
#include "miniwget.h"
|
#include "miniwget.h"
|
||||||
#include "connecthostport.h"
|
#include "connecthostport.h"
|
||||||
|
#include "receivedata.h"
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a HTTP response from a socket.
|
* Read a HTTP response from a socket.
|
||||||
* Process Content-Length and Transfer-encoding headers.
|
* Process Content-Length and Transfer-encoding headers.
|
||||||
|
* return a pointer to the content buffer, which length is saved
|
||||||
|
* to the length parameter.
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
getHTTPResponse(int s, int * size)
|
getHTTPResponse(int s, int * size)
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
int n;
|
int n;
|
||||||
int headers = 1;
|
int endofheaders = 0;
|
||||||
int chunked = 0;
|
int chunked = 0;
|
||||||
int content_length = -1;
|
int content_length = -1;
|
||||||
unsigned int chunksize = 0;
|
unsigned int chunksize = 0;
|
||||||
unsigned int bytestocopy = 0;
|
unsigned int bytestocopy = 0;
|
||||||
/* buffers : */
|
/* buffers : */
|
||||||
char * header_buf;
|
char * header_buf;
|
||||||
int header_buf_len = 2048;
|
unsigned int header_buf_len = 2048;
|
||||||
int header_buf_used = 0;
|
unsigned int header_buf_used = 0;
|
||||||
char * content_buf;
|
char * content_buf;
|
||||||
int content_buf_len = 2048;
|
unsigned int content_buf_len = 2048;
|
||||||
int content_buf_used = 0;
|
unsigned int content_buf_used = 0;
|
||||||
|
char chunksize_buf[32];
|
||||||
|
unsigned int chunksize_buf_index;
|
||||||
|
|
||||||
header_buf = malloc(header_buf_len);
|
header_buf = malloc(header_buf_len);
|
||||||
content_buf = malloc(content_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 i;
|
||||||
int linestart=0;
|
int linestart=0;
|
||||||
|
@ -86,17 +101,43 @@ getHTTPResponse(int s, int * size)
|
||||||
}
|
}
|
||||||
memcpy(header_buf + header_buf_used, buf, n);
|
memcpy(header_buf + header_buf_used, buf, n);
|
||||||
header_buf_used += 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]==':')
|
if(colon <= linestart && header_buf[i]==':')
|
||||||
{
|
{
|
||||||
colon = i;
|
colon = i;
|
||||||
while(i < (n-3)
|
while(i < (endofheaders-1)
|
||||||
&& (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
|
&& (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
|
||||||
i++;
|
i++;
|
||||||
valuestart = i + 1;
|
valuestart = i + 1;
|
||||||
}
|
}
|
||||||
/* detecting end of line */
|
/* 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)
|
if(colon > linestart && valuestart > colon)
|
||||||
{
|
{
|
||||||
|
@ -113,7 +154,7 @@ getHTTPResponse(int s, int * size)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
|
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
|
#ifdef DEBUG
|
||||||
printf("chunked transfer-encoding!\n");
|
printf("chunked transfer-encoding!\n");
|
||||||
|
@ -121,76 +162,19 @@ getHTTPResponse(int s, int * size)
|
||||||
chunked = 1;
|
chunked = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
linestart = i+2;
|
while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
|
||||||
|
i++;
|
||||||
|
linestart = i;
|
||||||
colon = linestart;
|
colon = linestart;
|
||||||
valuestart = 0;
|
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 */
|
/* content */
|
||||||
if(chunked)
|
if(chunked)
|
||||||
|
@ -201,19 +185,37 @@ getHTTPResponse(int s, int * size)
|
||||||
if(chunksize == 0)
|
if(chunksize == 0)
|
||||||
{
|
{
|
||||||
/* reading chunk size */
|
/* reading chunk size */
|
||||||
if(i<n && buf[i] == '\r') i++;
|
if(chunksize_buf_index == 0) {
|
||||||
if(i<n && buf[i] == '\n') i++;
|
/* skipping any leading CR LF */
|
||||||
while(i<n && isxdigit(buf[i]))
|
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_buf[chunksize_buf_index++] = buf[i];
|
||||||
chunksize = (chunksize << 4) + (buf[i] - '0');
|
chunksize_buf[chunksize_buf_index] = '\0';
|
||||||
else
|
|
||||||
chunksize = (chunksize << 4) + ((buf[i] | 32) - 'a' + 10);
|
|
||||||
i++;
|
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] == '\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
|
#ifdef DEBUG
|
||||||
printf("chunksize = %u (%x)\n", chunksize, chunksize);
|
printf("chunksize = %u (%x)\n", chunksize, chunksize);
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,12 +228,16 @@ getHTTPResponse(int s, int * size)
|
||||||
goto end_of_stream;
|
goto end_of_stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i);
|
bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
|
||||||
if((int)(content_buf_used + bytestocopy) > content_buf_len)
|
if((content_buf_used + bytestocopy) > content_buf_len)
|
||||||
{
|
{
|
||||||
content_buf = (char *)realloc((void *)content_buf,
|
if(content_length >= (int)(content_buf_used + bytestocopy)) {
|
||||||
content_buf_used + bytestocopy);
|
content_buf_len = content_length;
|
||||||
content_buf_len = content_buf_used + bytestocopy;
|
} 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);
|
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
|
||||||
content_buf_used += bytestocopy;
|
content_buf_used += bytestocopy;
|
||||||
|
@ -241,17 +247,28 @@ getHTTPResponse(int s, int * size)
|
||||||
}
|
}
|
||||||
else
|
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)
|
if(content_buf_used + n > content_buf_len)
|
||||||
{
|
{
|
||||||
content_buf = (char *)realloc((void *)content_buf,
|
if(content_length >= (int)(content_buf_used + n)) {
|
||||||
content_buf_used + n);
|
content_buf_len = content_length;
|
||||||
content_buf_len = content_buf_used + n;
|
} 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);
|
memcpy(content_buf + content_buf_used, buf, n);
|
||||||
content_buf_used += 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
|
#ifdef DEBUG
|
||||||
printf("End of HTTP content\n");
|
printf("End of HTTP content\n");
|
||||||
|
@ -274,29 +291,31 @@ end_of_stream:
|
||||||
* do all the work.
|
* do all the work.
|
||||||
* Return NULL if something failed. */
|
* Return NULL if something failed. */
|
||||||
static void *
|
static void *
|
||||||
miniwget3(const char * url, const char * host,
|
miniwget3(const char * host,
|
||||||
unsigned short port, const char * path,
|
unsigned short port, const char * path,
|
||||||
int * size, char * addr_str, int addr_str_len, const char * httpversion)
|
int * size, char * addr_str, int addr_str_len,
|
||||||
|
const char * httpversion, unsigned int scope_id)
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
int s;
|
int s;
|
||||||
int n;
|
int n;
|
||||||
int len;
|
int len;
|
||||||
int sent;
|
int sent;
|
||||||
|
void * content;
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
s = connecthostport(host, port);
|
s = connecthostport(host, port, scope_id);
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* get address for caller ! */
|
/* get address for caller ! */
|
||||||
if(addr_str)
|
if(addr_str)
|
||||||
{
|
{
|
||||||
struct sockaddr saddr;
|
struct sockaddr_storage saddr;
|
||||||
socklen_t saddrlen;
|
socklen_t saddrlen;
|
||||||
|
|
||||||
saddrlen = sizeof(saddr);
|
saddrlen = sizeof(saddr);
|
||||||
if(getsockname(s, &saddr, &saddrlen) < 0)
|
if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
|
||||||
{
|
{
|
||||||
perror("getsockname");
|
perror("getsockname");
|
||||||
}
|
}
|
||||||
|
@ -310,15 +329,28 @@ miniwget3(const char * url, const char * host,
|
||||||
{
|
{
|
||||||
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
|
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);
|
strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
|
||||||
#else
|
#else
|
||||||
/*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
|
#if 0
|
||||||
n = getnameinfo(&saddr, saddrlen,
|
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,
|
addr_str, addr_str_len,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
if(n != 0) {
|
if(n != 0) {
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
fprintf(stderr, "getnameinfo() failed : %d\n", n);
|
fprintf(stderr, "getnameinfo() failed : %d\n", n);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
|
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
|
||||||
|
@ -355,30 +387,37 @@ miniwget3(const char * url, const char * host,
|
||||||
sent += n;
|
sent += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getHTTPResponse(s, size);
|
content = getHTTPResponse(s, size);
|
||||||
|
closesocket(s);
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* miniwget2() :
|
/* miniwget2() :
|
||||||
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
|
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
|
||||||
static void *
|
static void *
|
||||||
miniwget2(const char * url, const char * host,
|
miniwget2(const char * host,
|
||||||
unsigned short port, const char * path,
|
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;
|
char * respbuffer;
|
||||||
|
|
||||||
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
|
#if 1
|
||||||
/*
|
respbuffer = miniwget3(host, port, path, size,
|
||||||
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
|
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)
|
if (*size == 0)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Retrying with HTTP/1.1\n");
|
printf("Retrying with HTTP/1.1\n");
|
||||||
#endif
|
#endif
|
||||||
free(respbuffer);
|
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;
|
return respbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,12 +429,15 @@ miniwget2(const char * url, const char * host,
|
||||||
* url : source string not modified
|
* url : source string not modified
|
||||||
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
|
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
|
||||||
* port : port (destination)
|
* port : port (destination)
|
||||||
* path : pointer to the path part of the URL
|
* path : pointer to the path part of the URL
|
||||||
*
|
*
|
||||||
* Return values :
|
* Return values :
|
||||||
* 0 - Failure
|
* 0 - Failure
|
||||||
* 1 - Success */
|
* 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;
|
char * p1, *p2, *p3;
|
||||||
if(!url)
|
if(!url)
|
||||||
|
@ -407,11 +449,75 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
|
||||||
if( (url[0]!='h') || (url[1]!='t')
|
if( (url[0]!='h') || (url[1]!='t')
|
||||||
||(url[2]!='t') || (url[3]!='p'))
|
||(url[2]!='t') || (url[3]!='p'))
|
||||||
return 0;
|
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, ':');
|
p2 = strchr(p1, ':');
|
||||||
p3 = strchr(p1, '/');
|
p3 = strchr(p1, '/');
|
||||||
if(!p3)
|
if(!p3)
|
||||||
return 0;
|
return 0;
|
||||||
memset(hostname, 0, MAXHOSTNAMELEN + 1);
|
|
||||||
if(!p2 || (p2>p3))
|
if(!p2 || (p2>p3))
|
||||||
{
|
{
|
||||||
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * miniwget(const char * url, int * size)
|
void *
|
||||||
|
miniwget(const char * url, int * size, unsigned int scope_id)
|
||||||
{
|
{
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
char * path;
|
char * path;
|
||||||
/* protocol://host:port/chemin */
|
/* protocol://host:port/chemin */
|
||||||
char hostname[MAXHOSTNAMELEN+1];
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
*size = 0;
|
*size = 0;
|
||||||
if(!parseURL(url, hostname, &port, &path))
|
if(!parseURL(url, hostname, &port, &path, &scope_id))
|
||||||
return NULL;
|
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;
|
unsigned short port;
|
||||||
char * path;
|
char * path;
|
||||||
/* protocol://host:port/chemin */
|
/* protocol://host:port/path */
|
||||||
char hostname[MAXHOSTNAMELEN+1];
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
*size = 0;
|
*size = 0;
|
||||||
if(addr)
|
if(addr)
|
||||||
addr[0] = '\0';
|
addr[0] = '\0';
|
||||||
if(!parseURL(url, hostname, &port, &path))
|
if(!parseURL(url, hostname, &port, &path, &scope_id))
|
||||||
return NULL;
|
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
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005 Thomas Bernard
|
* Copyright (c) 2005-2012 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution.
|
* LICENCE file provided in this distribution.
|
||||||
* */
|
* */
|
||||||
#ifndef __MINIWGET_H__
|
#ifndef MINIWGET_H_INCLUDED
|
||||||
#define __MINIWGET_H__
|
#define MINIWGET_H_INCLUDED
|
||||||
|
|
||||||
#include "declspec.h"
|
#include "declspec.h"
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@ extern "C" {
|
||||||
|
|
||||||
LIBSPEC void * getHTTPResponse(int s, int * size);
|
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
|
#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 ! */
|
/* minixml.c : the minimum size a xml parser can be ! */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
|
|
||||||
Copyright (c) 2005-2009, Thomas BERNARD
|
Copyright (c) 2005-2011, Thomas BERNARD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -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
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
#include <string.h>
|
||||||
#include "minixml.h"
|
#include "minixml.h"
|
||||||
|
|
||||||
/* parseatt : used to parse the argument list
|
/* parseatt : used to parse the argument list
|
||||||
|
@ -142,19 +143,43 @@ static void parseelt(struct xmlparser * p)
|
||||||
if (p->xml >= p->xmlend)
|
if (p->xml >= p->xmlend)
|
||||||
return;
|
return;
|
||||||
while( IS_WHITE_SPACE(*p->xml) )
|
while( IS_WHITE_SPACE(*p->xml) )
|
||||||
{
|
|
||||||
p->xml++;
|
|
||||||
if (p->xml >= p->xmlend)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while(*p->xml!='<')
|
|
||||||
{
|
{
|
||||||
i++; p->xml++;
|
i++; p->xml++;
|
||||||
if (p->xml >= p->xmlend)
|
if (p->xml >= p->xmlend)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(i>0 && p->datafunc)
|
if(memcmp(p->xml, "<![CDATA[", 9) == 0)
|
||||||
p->datafunc(p->data, data, i);
|
{
|
||||||
|
/* 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 == '/')
|
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
|
/* minimal xml parser
|
||||||
*
|
*
|
||||||
* Project : miniupnp
|
* Project : miniupnp
|
||||||
|
@ -8,8 +8,8 @@
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution.
|
* LICENCE file provided in this distribution.
|
||||||
* */
|
* */
|
||||||
#ifndef __MINIXML_H__
|
#ifndef MINIXML_H_INCLUDED
|
||||||
#define __MINIXML_H__
|
#define MINIXML_H_INCLUDED
|
||||||
#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n'))
|
#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n'))
|
||||||
|
|
||||||
/* if a callback function pointer is set to NULL,
|
/* 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
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution.
|
* LICENCE file provided in this distribution.
|
||||||
* */
|
* */
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "upnpcommands.h"
|
#include "upnpcommands.h"
|
||||||
#include "miniupnpc.h"
|
#include "miniupnpc.h"
|
||||||
|
#include "portlistingparse.h"
|
||||||
|
|
||||||
static UNSIGNED_INTEGER
|
static UNSIGNED_INTEGER
|
||||||
my_atoui(const char * s)
|
my_atoui(const char * s)
|
||||||
|
@ -24,15 +25,17 @@ UPNP_GetTotalBytesSent(const char * controlURL,
|
||||||
const char * servicetype)
|
const char * servicetype)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
unsigned int r = 0;
|
unsigned int r = 0;
|
||||||
char * p;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
|
p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
|
||||||
r = my_atoui(p);
|
r = my_atoui(p);
|
||||||
ClearNameValueList(&pdata);
|
ClearNameValueList(&pdata);
|
||||||
|
@ -46,15 +49,17 @@ UPNP_GetTotalBytesReceived(const char * controlURL,
|
||||||
const char * servicetype)
|
const char * servicetype)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
unsigned int r = 0;
|
unsigned int r = 0;
|
||||||
char * p;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
|
p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
|
||||||
r = my_atoui(p);
|
r = my_atoui(p);
|
||||||
ClearNameValueList(&pdata);
|
ClearNameValueList(&pdata);
|
||||||
|
@ -68,15 +73,17 @@ UPNP_GetTotalPacketsSent(const char * controlURL,
|
||||||
const char * servicetype)
|
const char * servicetype)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
unsigned int r = 0;
|
unsigned int r = 0;
|
||||||
char * p;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
|
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
|
||||||
r = my_atoui(p);
|
r = my_atoui(p);
|
||||||
ClearNameValueList(&pdata);
|
ClearNameValueList(&pdata);
|
||||||
|
@ -90,15 +97,17 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
|
||||||
const char * servicetype)
|
const char * servicetype)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
unsigned int r = 0;
|
unsigned int r = 0;
|
||||||
char * p;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
|
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
|
||||||
r = my_atoui(p);
|
r = my_atoui(p);
|
||||||
ClearNameValueList(&pdata);
|
ClearNameValueList(&pdata);
|
||||||
|
@ -110,13 +119,13 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
|
||||||
LIBSPEC int
|
LIBSPEC int
|
||||||
UPNP_GetStatusInfo(const char * controlURL,
|
UPNP_GetStatusInfo(const char * controlURL,
|
||||||
const char * servicetype,
|
const char * servicetype,
|
||||||
char * status,
|
char * status,
|
||||||
unsigned int * uptime,
|
unsigned int * uptime,
|
||||||
char * lastconnerror)
|
char * lastconnerror)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
char * p;
|
char * p;
|
||||||
char * up;
|
char * up;
|
||||||
char * err;
|
char * err;
|
||||||
|
@ -125,11 +134,13 @@ UPNP_GetStatusInfo(const char * controlURL,
|
||||||
if(!status && !uptime)
|
if(!status && !uptime)
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
up = GetValueFromNameValueList(&pdata, "NewUptime");
|
up = GetValueFromNameValueList(&pdata, "NewUptime");
|
||||||
p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
|
p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
|
||||||
err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
|
err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
|
||||||
|
@ -176,19 +187,20 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
|
||||||
char * connectionType)
|
char * connectionType)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
char * p;
|
char * p;
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
|
|
||||||
if(!connectionType)
|
if(!connectionType)
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
return UPNPCOMMAND_INVALID_ARGS;
|
||||||
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||||
"GetConnectionTypeInfo", 0, buffer, &bufsize) < 0) {
|
"GetConnectionTypeInfo", 0, &bufsize))) {
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
p = GetValueFromNameValueList(&pdata, "NewConnectionType");
|
p = GetValueFromNameValueList(&pdata, "NewConnectionType");
|
||||||
/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
|
/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
|
||||||
/* PossibleConnectionTypes will have several values.... */
|
/* PossibleConnectionTypes will have several values.... */
|
||||||
|
@ -209,18 +221,18 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
|
||||||
|
|
||||||
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
|
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
|
||||||
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
|
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
|
||||||
* One of the values can be null
|
* One of the values can be null
|
||||||
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
|
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
|
||||||
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
|
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
|
||||||
LIBSPEC int
|
LIBSPEC int
|
||||||
UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
||||||
const char * servicetype,
|
const char * servicetype,
|
||||||
unsigned int * bitrateDown,
|
unsigned int * bitrateDown,
|
||||||
unsigned int* bitrateUp)
|
unsigned int * bitrateUp)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
char * down;
|
char * down;
|
||||||
char * up;
|
char * up;
|
||||||
|
@ -230,19 +242,20 @@ UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
return UPNPCOMMAND_INVALID_ARGS;
|
||||||
|
|
||||||
/* shouldn't we use GetCommonLinkProperties ? */
|
/* shouldn't we use GetCommonLinkProperties ? */
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||||
"GetCommonLinkProperties", 0, buffer, &bufsize) < 0) {
|
"GetCommonLinkProperties", 0, &bufsize))) {
|
||||||
/*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
|
/*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
|
/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
|
||||||
/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
|
/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
|
||||||
down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
|
down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
|
||||||
up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
|
up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
|
||||||
/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
|
/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
|
||||||
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
|
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
|
||||||
if(down && up)
|
if(down && up)
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
ret = UPNPCOMMAND_SUCCESS;
|
||||||
|
|
||||||
|
@ -272,7 +285,7 @@ UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
||||||
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
|
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
|
||||||
* if the third arg is not null the value is copied to it.
|
* 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 :
|
* Return values :
|
||||||
* 0 : SUCCESS
|
* 0 : SUCCESS
|
||||||
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
|
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
|
||||||
|
@ -286,19 +299,21 @@ UPNP_GetExternalIPAddress(const char * controlURL,
|
||||||
char * extIpAdd)
|
char * extIpAdd)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
char * p;
|
char * p;
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
|
|
||||||
if(!extIpAdd || !controlURL || !servicetype)
|
if(!extIpAdd || !controlURL || !servicetype)
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
|
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
|
||||||
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
|
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
|
||||||
if(p) {
|
if(p) {
|
||||||
|
@ -325,11 +340,12 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
||||||
const char * inClient,
|
const char * inClient,
|
||||||
const char * desc,
|
const char * desc,
|
||||||
const char * proto,
|
const char * proto,
|
||||||
const char * remoteHost)
|
const char * remoteHost,
|
||||||
|
const char * leaseDuration)
|
||||||
{
|
{
|
||||||
struct UPNParg * AddPortMappingArgs;
|
struct UPNParg * AddPortMappingArgs;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
const char * resVal;
|
const char * resVal;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -353,8 +369,10 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
||||||
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
|
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
|
||||||
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
|
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
|
||||||
AddPortMappingArgs[7].elt = "NewLeaseDuration";
|
AddPortMappingArgs[7].elt = "NewLeaseDuration";
|
||||||
AddPortMappingArgs[7].val = "0";
|
AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize) < 0) {
|
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||||
|
"AddPortMapping", AddPortMappingArgs,
|
||||||
|
&bufsize))) {
|
||||||
free(AddPortMappingArgs);
|
free(AddPortMappingArgs);
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -362,6 +380,7 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
||||||
/*buffer[bufsize] = '\0';*/
|
/*buffer[bufsize] = '\0';*/
|
||||||
/*puts(buffer);*/
|
/*puts(buffer);*/
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||||
if(resVal) {
|
if(resVal) {
|
||||||
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
|
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
|
||||||
|
@ -382,8 +401,8 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
||||||
{
|
{
|
||||||
/*struct NameValueParserData pdata;*/
|
/*struct NameValueParserData pdata;*/
|
||||||
struct UPNParg * DeletePortMappingArgs;
|
struct UPNParg * DeletePortMappingArgs;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
const char * resVal;
|
const char * resVal;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -398,14 +417,15 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
||||||
DeletePortMappingArgs[1].val = extPort;
|
DeletePortMappingArgs[1].val = extPort;
|
||||||
DeletePortMappingArgs[2].elt = "NewProtocol";
|
DeletePortMappingArgs[2].elt = "NewProtocol";
|
||||||
DeletePortMappingArgs[2].val = proto;
|
DeletePortMappingArgs[2].val = proto;
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||||
"DeletePortMapping",
|
"DeletePortMapping",
|
||||||
DeletePortMappingArgs, buffer, &bufsize) < 0 ) {
|
DeletePortMappingArgs, &bufsize))) {
|
||||||
free(DeletePortMappingArgs);
|
free(DeletePortMappingArgs);
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||||
if(resVal) {
|
if(resVal) {
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
|
@ -433,8 +453,8 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
struct UPNParg * GetPortMappingArgs;
|
struct UPNParg * GetPortMappingArgs;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
char * p;
|
char * p;
|
||||||
int r = UPNPCOMMAND_UNKNOWN_ERROR;
|
int r = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
if(!index)
|
if(!index)
|
||||||
|
@ -444,13 +464,15 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
||||||
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
|
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
|
||||||
GetPortMappingArgs[0].elt = "NewPortMappingIndex";
|
GetPortMappingArgs[0].elt = "NewPortMappingIndex";
|
||||||
GetPortMappingArgs[0].val = index;
|
GetPortMappingArgs[0].val = index;
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||||
"GetGenericPortMappingEntry",
|
"GetGenericPortMappingEntry",
|
||||||
GetPortMappingArgs, buffer, &bufsize) < 0) {
|
GetPortMappingArgs, &bufsize))) {
|
||||||
free(GetPortMappingArgs);
|
free(GetPortMappingArgs);
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
|
p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
|
||||||
if(p && rHost)
|
if(p && rHost)
|
||||||
{
|
{
|
||||||
|
@ -517,17 +539,20 @@ UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
|
||||||
unsigned int * numEntries)
|
unsigned int * numEntries)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
char* p;
|
char* p;
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
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;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DisplayNameValueList(buffer, bufsize);
|
DisplayNameValueList(buffer, bufsize);
|
||||||
#endif
|
#endif
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
|
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
|
||||||
if(numEntries && p) {
|
if(numEntries && p) {
|
||||||
|
@ -555,12 +580,15 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
||||||
const char * extPort,
|
const char * extPort,
|
||||||
const char * proto,
|
const char * proto,
|
||||||
char * intClient,
|
char * intClient,
|
||||||
char * intPort)
|
char * intPort,
|
||||||
|
char * desc,
|
||||||
|
char * enabled,
|
||||||
|
char * leaseDuration)
|
||||||
{
|
{
|
||||||
struct NameValueParserData pdata;
|
struct NameValueParserData pdata;
|
||||||
struct UPNParg * GetPortMappingArgs;
|
struct UPNParg * GetPortMappingArgs;
|
||||||
char buffer[4096];
|
char * buffer;
|
||||||
int bufsize = 4096;
|
int bufsize;
|
||||||
char * p;
|
char * p;
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
|
|
||||||
|
@ -569,18 +597,20 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
||||||
|
|
||||||
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
||||||
GetPortMappingArgs[0].elt = "NewRemoteHost";
|
GetPortMappingArgs[0].elt = "NewRemoteHost";
|
||||||
|
/* TODO : add remote host ? */
|
||||||
GetPortMappingArgs[1].elt = "NewExternalPort";
|
GetPortMappingArgs[1].elt = "NewExternalPort";
|
||||||
GetPortMappingArgs[1].val = extPort;
|
GetPortMappingArgs[1].val = extPort;
|
||||||
GetPortMappingArgs[2].elt = "NewProtocol";
|
GetPortMappingArgs[2].elt = "NewProtocol";
|
||||||
GetPortMappingArgs[2].val = proto;
|
GetPortMappingArgs[2].val = proto;
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||||
"GetSpecificPortMappingEntry",
|
"GetSpecificPortMappingEntry",
|
||||||
GetPortMappingArgs, buffer, &bufsize) < 0) {
|
GetPortMappingArgs, &bufsize))) {
|
||||||
free(GetPortMappingArgs);
|
free(GetPortMappingArgs);
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
return UPNPCOMMAND_HTTP_ERROR;
|
||||||
}
|
}
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
/*DisplayNameValueList(buffer, bufsize);*/
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
ParseNameValue(buffer, bufsize, &pdata);
|
||||||
|
free(buffer); buffer = NULL;
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
||||||
if(p) {
|
if(p) {
|
||||||
|
@ -597,6 +627,25 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
||||||
} else
|
} else
|
||||||
intPort[0] = '\0';
|
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");
|
p = GetValueFromNameValueList(&pdata, "errorCode");
|
||||||
if(p) {
|
if(p) {
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||||
|
@ -608,4 +657,441 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
||||||
return ret;
|
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/
|
/* Miniupnp project : http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* 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
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided within this distribution */
|
* LICENCE file provided within this distribution */
|
||||||
#ifndef __UPNPCOMMANDS_H__
|
#ifndef UPNPCOMMANDS_H_INCLUDED
|
||||||
#define __UPNPCOMMANDS_H__
|
#define UPNPCOMMANDS_H_INCLUDED
|
||||||
|
|
||||||
#include "upnpreplyparse.h"
|
#include "upnpreplyparse.h"
|
||||||
|
#include "portlistingparse.h"
|
||||||
#include "declspec.h"
|
#include "declspec.h"
|
||||||
|
#include "miniupnpctypes.h"
|
||||||
|
|
||||||
/* MiniUPnPc return codes : */
|
/* MiniUPnPc return codes : */
|
||||||
#define UPNPCOMMAND_SUCCESS (0)
|
#define UPNPCOMMAND_SUCCESS (0)
|
||||||
|
@ -20,14 +22,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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
|
LIBSPEC UNSIGNED_INTEGER
|
||||||
UPNP_GetTotalBytesSent(const char * controlURL,
|
UPNP_GetTotalBytesSent(const char * controlURL,
|
||||||
const char * servicetype);
|
const char * servicetype);
|
||||||
|
@ -68,12 +62,12 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
|
||||||
|
|
||||||
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
|
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
|
||||||
* if the third arg is not null the value is copied to it.
|
* 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 :
|
* Return values :
|
||||||
* 0 : SUCCESS
|
* 0 : SUCCESS
|
||||||
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
|
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
|
||||||
*
|
*
|
||||||
* possible UPnP Errors :
|
* possible UPnP Errors :
|
||||||
* 402 Invalid Args - See UPnP Device Architecture section on Control.
|
* 402 Invalid Args - See UPnP Device Architecture section on Control.
|
||||||
* 501 Action Failed - 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 :
|
* Return values :
|
||||||
* 0 : SUCCESS
|
* 0 : SUCCESS
|
||||||
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
|
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
|
||||||
*
|
*
|
||||||
* List of possible UPnP errors for AddPortMapping :
|
* List of possible UPnP errors for AddPortMapping :
|
||||||
* errorCode errorDescription (short) - Description (long)
|
* errorCode errorDescription (short) - Description (long)
|
||||||
* 402 Invalid Args - See UPnP Device Architecture section on Control.
|
* 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
|
* 718 ConflictInMappingEntry - The port mapping entry specified conflicts
|
||||||
* with a mapping assigned previously to another client
|
* with a mapping assigned previously to another client
|
||||||
* 724 SamePortValuesRequired - Internal and External port values
|
* 724 SamePortValuesRequired - Internal and External port values
|
||||||
* must be the same
|
* must be the same
|
||||||
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
|
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
|
||||||
* permanent lease times on port mappings
|
* permanent lease times on port mappings
|
||||||
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
|
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
|
||||||
|
@ -126,7 +120,8 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
||||||
const char * inClient,
|
const char * inClient,
|
||||||
const char * desc,
|
const char * desc,
|
||||||
const char * proto,
|
const char * proto,
|
||||||
const char * remoteHost);
|
const char * remoteHost,
|
||||||
|
const char * leaseDuration);
|
||||||
|
|
||||||
/* UPNP_DeletePortMapping()
|
/* UPNP_DeletePortMapping()
|
||||||
* Use same argument values as what was used for AddPortMapping().
|
* Use same argument values as what was used for AddPortMapping().
|
||||||
|
@ -146,11 +141,20 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
||||||
/* UPNP_GetPortMappingNumberOfEntries()
|
/* UPNP_GetPortMappingNumberOfEntries()
|
||||||
* not supported by all routers */
|
* not supported by all routers */
|
||||||
LIBSPEC int
|
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
|
/* UPNP_GetSpecificPortMappingEntry()
|
||||||
* the result is returned in the intClient and intPort strings
|
* retrieves an existing port mapping
|
||||||
* please provide 16 and 6 bytes of data
|
* 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 :
|
* return value :
|
||||||
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
||||||
|
@ -161,9 +165,22 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
||||||
const char * extPort,
|
const char * extPort,
|
||||||
const char * proto,
|
const char * proto,
|
||||||
char * intClient,
|
char * intClient,
|
||||||
char * intPort);
|
char * intPort,
|
||||||
|
char * desc,
|
||||||
|
char * enabled,
|
||||||
|
char * leaseDuration);
|
||||||
|
|
||||||
/* UPNP_GetGenericPortMappingEntry()
|
/* 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 :
|
* return value :
|
||||||
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
||||||
|
@ -186,6 +203,66 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
||||||
char * rHost,
|
char * rHost,
|
||||||
char * duration);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
/* Project : miniupnp
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
* copyright (c) 2007 Thomas Bernard
|
* copyright (c) 2007 Thomas Bernard
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "upnperrors.h"
|
#include "upnperrors.h"
|
||||||
#include "upnpcommands.h"
|
#include "upnpcommands.h"
|
||||||
|
#include "miniupnpc.h"
|
||||||
|
|
||||||
const char * strupnperror(int err)
|
const char * strupnperror(int err)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +24,12 @@ const char * strupnperror(int err)
|
||||||
case UPNPCOMMAND_INVALID_ARGS:
|
case UPNPCOMMAND_INVALID_ARGS:
|
||||||
s = "Miniupnpc Invalid Arguments";
|
s = "Miniupnpc Invalid Arguments";
|
||||||
break;
|
break;
|
||||||
|
case UPNPDISCOVER_SOCKET_ERROR:
|
||||||
|
s = "Miniupnpc Socket error";
|
||||||
|
break;
|
||||||
|
case UPNPDISCOVER_MEMORY_ERROR:
|
||||||
|
s = "Miniupnpc Memory allocation error";
|
||||||
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
s = "Invalid Action";
|
s = "Invalid Action";
|
||||||
break;
|
break;
|
||||||
|
@ -32,6 +39,36 @@ const char * strupnperror(int err)
|
||||||
case 501:
|
case 501:
|
||||||
s = "Action Failed";
|
s = "Action Failed";
|
||||||
break;
|
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:
|
case 713:
|
||||||
s = "SpecifiedArrayIndexInvalid";
|
s = "SpecifiedArrayIndexInvalid";
|
||||||
break;
|
break;
|
||||||
|
@ -60,7 +97,8 @@ const char * strupnperror(int err)
|
||||||
s = "ExternalPortOnlySupportsWildcard";
|
s = "ExternalPortOnlySupportsWildcard";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
s = NULL;
|
s = "UnknownError";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return s;
|
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
|
/* (c) 2007 Thomas Bernard
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* MiniUPnP Project.
|
* MiniUPnP Project.
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* This software is subjet to the conditions detailed in the
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENCE file. */
|
* provided LICENCE file. */
|
||||||
#ifndef __UPNPERRORS_H__
|
#ifndef UPNPERRORS_H_INCLUDED
|
||||||
#define __UPNPERRORS_H__
|
#define UPNPERRORS_H_INCLUDED
|
||||||
|
|
||||||
#include "declspec.h"
|
#include "declspec.h"
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* strupnperror()
|
/* strupnperror()
|
||||||
* Return a string description of the UPnP error code
|
* Return a string description of the UPnP error code
|
||||||
* or NULL for undefinded errors */
|
* or NULL for undefinded errors */
|
||||||
LIBSPEC const char * strupnperror(int err);
|
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
|
/* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* 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
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
|
@ -15,40 +15,90 @@
|
||||||
static void
|
static void
|
||||||
NameValueParserStartElt(void * d, const char * name, int l)
|
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)
|
if(l>63)
|
||||||
l = 63;
|
l = 63;
|
||||||
memcpy(data->curelt, name, l);
|
memcpy(data->curelt, name, l);
|
||||||
data->curelt[l] = '\0';
|
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
|
static void
|
||||||
NameValueParserGetData(void * d, const char * datas, int l)
|
NameValueParserGetData(void * d, const char * datas, int l)
|
||||||
{
|
{
|
||||||
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
||||||
struct NameValue * nv;
|
if(strcmp(data->curelt, "NewPortListing") == 0)
|
||||||
nv = malloc(sizeof(struct NameValue));
|
{
|
||||||
if(l>63)
|
/* specific case for NewPortListing which is a XML Document */
|
||||||
l = 63;
|
data->portListing = malloc(l + 1);
|
||||||
strncpy(nv->name, data->curelt, 64);
|
if(!data->portListing)
|
||||||
nv->name[63] = '\0';
|
{
|
||||||
memcpy(nv->value, datas, l);
|
/* malloc error */
|
||||||
nv->value[l] = '\0';
|
return;
|
||||||
LIST_INSERT_HEAD( &(data->head), nv, entries);
|
}
|
||||||
|
memcpy(data->portListing, datas, l);
|
||||||
|
data->portListing[l] = '\0';
|
||||||
|
data->portListingLength = l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* standard case. */
|
||||||
|
data->cdata = datas;
|
||||||
|
data->cdatalen = l;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ParseNameValue(const char * buffer, int bufsize,
|
ParseNameValue(const char * buffer, int bufsize,
|
||||||
struct NameValueParserData * data)
|
struct NameValueParserData * data)
|
||||||
{
|
{
|
||||||
struct xmlparser parser;
|
struct xmlparser parser;
|
||||||
LIST_INIT(&(data->head));
|
LIST_INIT(&(data->head));
|
||||||
|
data->portListing = NULL;
|
||||||
|
data->portListingLength = 0;
|
||||||
/* init xmlparser object */
|
/* init xmlparser object */
|
||||||
parser.xmlstart = buffer;
|
parser.xmlstart = buffer;
|
||||||
parser.xmlsize = bufsize;
|
parser.xmlsize = bufsize;
|
||||||
parser.data = data;
|
parser.data = data;
|
||||||
parser.starteltfunc = NameValueParserStartElt;
|
parser.starteltfunc = NameValueParserStartElt;
|
||||||
parser.endeltfunc = 0;
|
parser.endeltfunc = NameValueParserEndElt;
|
||||||
parser.datafunc = NameValueParserGetData;
|
parser.datafunc = NameValueParserGetData;
|
||||||
parser.attfunc = 0;
|
parser.attfunc = 0;
|
||||||
parsexml(&parser);
|
parsexml(&parser);
|
||||||
|
@ -58,6 +108,12 @@ void
|
||||||
ClearNameValueList(struct NameValueParserData * pdata)
|
ClearNameValueList(struct NameValueParserData * pdata)
|
||||||
{
|
{
|
||||||
struct NameValue * nv;
|
struct NameValue * nv;
|
||||||
|
if(pdata->portListing)
|
||||||
|
{
|
||||||
|
free(pdata->portListing);
|
||||||
|
pdata->portListing = NULL;
|
||||||
|
pdata->portListingLength = 0;
|
||||||
|
}
|
||||||
while((nv = pdata->head.lh_first) != NULL)
|
while((nv = pdata->head.lh_first) != NULL)
|
||||||
{
|
{
|
||||||
LIST_REMOVE(nv, entries);
|
LIST_REMOVE(nv, entries);
|
||||||
|
@ -65,7 +121,7 @@ ClearNameValueList(struct NameValueParserData * pdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
||||||
const char * Name)
|
const char * Name)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +162,7 @@ GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* debug all-in-one function
|
/* debug all-in-one function
|
||||||
* do parsing then display to stdout */
|
* do parsing then display to stdout */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void
|
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
|
/* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* 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
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
#ifndef __UPNPREPLYPARSE_H__
|
#ifndef UPNPREPLYPARSE_H_INCLUDED
|
||||||
#define __UPNPREPLYPARSE_H__
|
#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"
|
#include "bsdqueue.h"
|
||||||
#else
|
#else
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
@ -21,12 +21,17 @@ extern "C" {
|
||||||
struct NameValue {
|
struct NameValue {
|
||||||
LIST_ENTRY(NameValue) entries;
|
LIST_ENTRY(NameValue) entries;
|
||||||
char name[64];
|
char name[64];
|
||||||
char value[64];
|
char value[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NameValueParserData {
|
struct NameValueParserData {
|
||||||
LIST_HEAD(listhead, NameValue) head;
|
LIST_HEAD(listhead, NameValue) head;
|
||||||
char curelt[64];
|
char curelt[64];
|
||||||
|
char * portListing;
|
||||||
|
int portListingLength;
|
||||||
|
int topelt;
|
||||||
|
const char * cdata;
|
||||||
|
int cdatalen;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ParseNameValue() */
|
/* ParseNameValue() */
|
||||||
|
@ -43,10 +48,12 @@ char *
|
||||||
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
||||||
const char * Name);
|
const char * Name);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* GetValueFromNameValueListIgnoreNS() */
|
/* GetValueFromNameValueListIgnoreNS() */
|
||||||
char *
|
char *
|
||||||
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
|
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
|
||||||
const char * Name);
|
const char * Name);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* DisplayNameValueList() */
|
/* DisplayNameValueList() */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
2013-xx-xx: Version 3.1.1
|
2013-xx-xx: Version 3.1.1
|
||||||
* General:
|
* General:
|
||||||
* Change: Simplify build process by getting rid of bison/flex dependencies (commit:d13bc0de7dd0588351af24dc45d55110d0eed6e8)
|
|
||||||
* Change: Filter out bad maps (commit:acfe83cdf6f44660276ba73931e2cebdc8a250ac)
|
* 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: 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: 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: Bug that made droids produced by scripts get human player's upgrades (commit:8149dc94c0b61117982281cdaf2aac1bec2525e9)
|
||||||
* Fix: Backwards terrain shadows (commit:85ecd9a3937e7843d9eb4798572651f950bd7555)
|
* Fix: Backwards terrain shadows (commit:85ecd9a3937e7843d9eb4798572651f950bd7555)
|
||||||
* Fix: Mod loading bug (commit:87cade1a684f3da0572f13e92539100f35b4f6fe, ticket:3567)
|
* Fix: Mod loading bug (commit:87cade1a684f3da0572f13e92539100f35b4f6fe, ticket:3567)
|
||||||
|
@ -25,7 +24,9 @@
|
||||||
* Fix: Add parameter checking for buildings that do not exist (commit:e38de7b64242a547acd77c7775dbfae10c74ca3d)
|
* Fix: Add parameter checking for buildings that do not exist (commit:e38de7b64242a547acd77c7775dbfae10c74ca3d)
|
||||||
* Maps:
|
* Maps:
|
||||||
* Fix: Remove lop-sided oil barrels from 4c-pyramidal (commit:6092fe1194529f0c7fe023d9c98973e44f9f9f24)
|
* Fix: Remove lop-sided oil barrels from 4c-pyramidal (commit:6092fe1194529f0c7fe023d9c98973e44f9f9f24)
|
||||||
|
* Add: Gamma (3p) and Melting (6p) by NoQ (commit:b8bdf44737e1d9423c2581b1377cf1be9c4a3666)
|
||||||
* Build system:
|
* 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)
|
* Fix: Building on OpenBSD (commit:9b9383500fb4c1dd5270a68e3490dc358e2da55f, ticket:3917, commit:47a6d6d4684b993d15e378f6d0877fa043b26ca0, ticket:3845)
|
||||||
|
|
||||||
2012-12-09: Version 3.1.0
|
2012-12-09: Version 3.1.0
|
||||||
|
|
|
@ -142,14 +142,15 @@ static SocketSet* socket_set = NULL;
|
||||||
|
|
||||||
// UPnP
|
// UPnP
|
||||||
static int upnp = false;
|
static int upnp = false;
|
||||||
static bool upnp_done = false;
|
|
||||||
WZ_THREAD *upnpdiscover;
|
WZ_THREAD *upnpdiscover;
|
||||||
|
|
||||||
static struct UPNPUrls urls;
|
static struct UPNPUrls urls;
|
||||||
static struct IGDdatas data;
|
static struct IGDdatas data;
|
||||||
|
|
||||||
// local ip address
|
// local ip address
|
||||||
static char lanaddr[16];
|
static char lanaddr[40];
|
||||||
|
static char externalIPAddress[40];
|
||||||
/**
|
/**
|
||||||
* Used for connections with clients.
|
* Used for connections with clients.
|
||||||
*/
|
*/
|
||||||
|
@ -934,7 +935,6 @@ static bool NETrecvGAMESTRUCT(GAMESTRUCT* ourgamestruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int upnp_init(void *asdf)
|
static int upnp_init(void *asdf)
|
||||||
{
|
{
|
||||||
struct UPNPDev *devlist;
|
struct UPNPDev *devlist;
|
||||||
|
@ -942,14 +942,14 @@ static int upnp_init(void *asdf)
|
||||||
char *descXML;
|
char *descXML;
|
||||||
int descXMLsize = 0;
|
int descXMLsize = 0;
|
||||||
char buf[255];
|
char buf[255];
|
||||||
|
int result;
|
||||||
memset(&urls, 0, sizeof(struct UPNPUrls));
|
memset(&urls, 0, sizeof(struct UPNPUrls));
|
||||||
memset(&data, 0, sizeof(struct IGDdatas));
|
memset(&data, 0, sizeof(struct IGDdatas));
|
||||||
|
|
||||||
if (NetPlay.isUPNP)
|
if (NetPlay.isUPNP)
|
||||||
{
|
{
|
||||||
debug(LOG_NET, "Searching for UPnP devices for automatic port forwarding...");
|
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.");
|
debug(LOG_NET, "UPnP device search finished.");
|
||||||
if (devlist)
|
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);
|
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);
|
debug(LOG_NET, "LAN address: %s", lanaddr);
|
||||||
if (descXML)
|
if (descXML)
|
||||||
{
|
{
|
||||||
parserootdesc (descXML, descXMLsize, &data);
|
parserootdesc (descXML, descXMLsize, &data);
|
||||||
free (descXML); descXML = 0;
|
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);
|
ssprintf(buf, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr);
|
||||||
addDumpInfo(buf);
|
addDumpInfo(buf);
|
||||||
|
@ -983,13 +983,20 @@ static int upnp_init(void *asdf)
|
||||||
{
|
{
|
||||||
ssprintf(buf, "controlURL not available, UPnP disabled");
|
ssprintf(buf, "controlURL not available, UPnP disabled");
|
||||||
addDumpInfo(buf);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NETaddRedirects();
|
||||||
|
upnp = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ssprintf(buf, "UPnP device not found.");
|
ssprintf(buf, "UPnP device not found.");
|
||||||
addDumpInfo(buf);
|
addDumpInfo(buf);
|
||||||
debug(LOG_NET, "No UPnP devices found.");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -999,55 +1006,74 @@ static int upnp_init(void *asdf)
|
||||||
debug(LOG_NET, "UPnP detection routine disabled by user.");
|
debug(LOG_NET, "UPnP detection routine disabled by user.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool upnp_add_redirect(int port)
|
static bool upnp_add_redirect(int port)
|
||||||
{
|
{
|
||||||
char externalIP[16];
|
|
||||||
char port_str[16];
|
char port_str[16];
|
||||||
|
char buf[512]={'\0'};
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
debug(LOG_NET, "upnp_add_redir(%d)\n", port);
|
debug(LOG_NET, "upnp_add_redir(%d)", port);
|
||||||
UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP);
|
|
||||||
sprintf(port_str, "%d", port);
|
sprintf(port_str, "%d", port);
|
||||||
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
|
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)
|
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 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];
|
char port_str[16];
|
||||||
debug(LOG_NET, "upnp_rem_redir(%d)", port);
|
debug(LOG_NET, "upnp_rem_redir(%d)", port);
|
||||||
sprintf(port_str, "%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)
|
void NETaddRedirects(void)
|
||||||
{
|
{
|
||||||
debug(LOG_NET, "%s\n", __FUNCTION__);
|
if (upnp_add_redirect(gameserver_port))
|
||||||
if (!upnp_done)
|
|
||||||
{
|
{
|
||||||
upnp = wzThreadJoin(upnpdiscover);
|
debug(LOG_NET, "successful!");
|
||||||
upnp_done = true;
|
|
||||||
}
|
}
|
||||||
if (upnp) {
|
else
|
||||||
upnp_add_redirect(gameserver_port);
|
{
|
||||||
|
debug(LOG_NET, "failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NETremRedirects(void)
|
void NETremRedirects(void)
|
||||||
{
|
{
|
||||||
debug(LOG_NET, "%s\n", __FUNCTION__);
|
debug(LOG_NET, "upnp is %d", upnp);
|
||||||
if (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" );
|
debug( LOG_NET, "NETshutdown" );
|
||||||
NETlogEntry("NETshutdown", SYNC_FLAG, selectedPlayer);
|
NETlogEntry("NETshutdown", SYNC_FLAG, selectedPlayer);
|
||||||
|
if (NetPlay.bComms && NetPlay.isUPNP)
|
||||||
|
{
|
||||||
|
NETremRedirects();
|
||||||
|
}
|
||||||
NETstopLogging();
|
NETstopLogging();
|
||||||
if (IPlist)
|
if (IPlist)
|
||||||
free(IPlist);
|
free(IPlist);
|
||||||
|
@ -1108,11 +1138,6 @@ int NETshutdown(void)
|
||||||
NETdeleteQueue();
|
NETdeleteQueue();
|
||||||
SOCKETshutdown();
|
SOCKETshutdown();
|
||||||
|
|
||||||
if (NetPlay.bComms && NetPlay.isUPNP)
|
|
||||||
{
|
|
||||||
NETremRedirects();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset net usage statistics.
|
// Reset net usage statistics.
|
||||||
nStats = nZeroStats;
|
nStats = nZeroStats;
|
||||||
nStatsLastSec = nZeroStats;
|
nStatsLastSec = nZeroStats;
|
||||||
|
@ -2587,10 +2612,6 @@ bool NEThostGame(const char* SessionName, const char* PlayerName,
|
||||||
mapDownloadProgress = 100;
|
mapDownloadProgress = 100;
|
||||||
netPlayersUpdated = true;
|
netPlayersUpdated = true;
|
||||||
|
|
||||||
if (NetPlay.bComms && NetPlay.isUPNP)
|
|
||||||
{
|
|
||||||
NETaddRedirects();
|
|
||||||
}
|
|
||||||
NET_InitPlayers();
|
NET_InitPlayers();
|
||||||
for (unsigned n = 0; n < MAX_PLAYERS_IN_GUI; ++n)
|
for (unsigned n = 0; n < MAX_PLAYERS_IN_GUI; ++n)
|
||||||
{
|
{
|
||||||
|
|
|
@ -207,6 +207,8 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\3rdparty\miniupnpc\connecthostport.c" />
|
<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="netjoin_stub.cpp" />
|
||||||
<ClCompile Include="netlog.cpp" />
|
<ClCompile Include="netlog.cpp" />
|
||||||
<ClCompile Include="netplay.cpp" />
|
<ClCompile Include="netplay.cpp" />
|
||||||
|
@ -246,8 +248,11 @@
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\minissdpc.h" />
|
<ClInclude Include="..\..\3rdparty\miniupnpc\minissdpc.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpc.h" />
|
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpc.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpcstrings.h" />
|
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpcstrings.h" />
|
||||||
|
<ClInclude Include="..\..\3rdparty\miniupnpc\miniupnpctypes.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\miniwget.h" />
|
<ClInclude Include="..\..\3rdparty\miniupnpc\miniwget.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\minixml.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\upnpcommands.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\upnperrors.h" />
|
<ClInclude Include="..\..\3rdparty\miniupnpc\upnperrors.h" />
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpreplyparse.h" />
|
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpreplyparse.h" />
|
||||||
|
|
|
@ -68,6 +68,12 @@
|
||||||
<ClCompile Include="netjoin_stub.cpp">
|
<ClCompile Include="netjoin_stub.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\3rdparty\miniupnpc\bsdqueue.h">
|
<ClInclude Include="..\..\3rdparty\miniupnpc\bsdqueue.h">
|
||||||
|
@ -127,5 +133,14 @@
|
||||||
<ClInclude Include="nettypes.h">
|
<ClInclude Include="nettypes.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -537,11 +537,11 @@ bool runMultiPlayerMenu(void)
|
||||||
case FRONTEND_HOST:
|
case FRONTEND_HOST:
|
||||||
// don't pretend we are running a network game. Really do it!
|
// don't pretend we are running a network game. Really do it!
|
||||||
NetPlay.bComms = true; // use network = true
|
NetPlay.bComms = true; // use network = true
|
||||||
NETdiscoverUPnPDevices();
|
|
||||||
ingame.bHostSetup = true;
|
ingame.bHostSetup = true;
|
||||||
bMultiPlayer = true;
|
bMultiPlayer = true;
|
||||||
bMultiMessages = true;
|
bMultiMessages = true;
|
||||||
NETinit(true);
|
NETinit(true);
|
||||||
|
NETdiscoverUPnPDevices();
|
||||||
game.type = SKIRMISH; // needed?
|
game.type = SKIRMISH; // needed?
|
||||||
lastTitleMode = MULTI;
|
lastTitleMode = MULTI;
|
||||||
changeTitleMode(MULTIOPTION);
|
changeTitleMode(MULTIOPTION);
|
||||||
|
|
|
@ -3780,9 +3780,22 @@ bool startMultiOptions(bool bReenter)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char buf[512] = {'\0'};
|
||||||
addPlayerBox(false); // Players
|
addPlayerBox(false); // Players
|
||||||
addGameOptions();
|
addGameOptions();
|
||||||
addChatBox();
|
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..
|
// going back to multiop after setting limits up..
|
||||||
|
|
Loading…
Reference in New Issue