From 569c5e77fdd247f59d48d1732dbea6a69bc7d6b3 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 28 Jul 2015 14:48:26 -0700 Subject: [PATCH] Add binary build of libminiupnpc for Mac x64. --- ext/bin/miniupnpc/Changelog.txt | 633 ++++++++++++++++++ ext/bin/miniupnpc/LICENSE | 27 + ext/bin/miniupnpc/README.md | 4 + ext/bin/miniupnpc/VERSION | 1 + .../miniupnpc/include/miniupnpc/codelength.h | 54 ++ .../include/miniupnpc/connecthostport.h | 18 + .../include/miniupnpc/igd_desc_parse.h | 49 ++ .../miniupnpc/include/miniupnpc/minisoap.h | 15 + .../miniupnpc/include/miniupnpc/minissdpc.h | 15 + .../miniupnpc/include/miniupnpc/miniupnpc.h | 154 +++++ .../include/miniupnpc/miniupnpc_declspec.h | 21 + .../include/miniupnpc/miniupnpcstrings.h | 23 + .../include/miniupnpc/miniupnpctypes.h | 19 + .../miniupnpc/include/miniupnpc/miniwget.h | 30 + ext/bin/miniupnpc/include/miniupnpc/minixml.h | 37 + .../include/miniupnpc/portlistingparse.h | 65 ++ .../miniupnpc/include/miniupnpc/receivedata.h | 19 + .../include/miniupnpc/upnpcommands.h | 348 ++++++++++ .../miniupnpc/include/miniupnpc/upnperrors.h | 26 + .../include/miniupnpc/upnpreplyparse.h | 63 ++ ext/bin/miniupnpc/mac-x64/libminiupnpc.a | Bin 0 -> 95616 bytes make-mac.mk | 8 +- service/OneService.cpp | 4 +- 23 files changed, 1628 insertions(+), 5 deletions(-) create mode 100644 ext/bin/miniupnpc/Changelog.txt create mode 100644 ext/bin/miniupnpc/LICENSE create mode 100644 ext/bin/miniupnpc/README.md create mode 100644 ext/bin/miniupnpc/VERSION create mode 100644 ext/bin/miniupnpc/include/miniupnpc/codelength.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/connecthostport.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/igd_desc_parse.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/minisoap.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/minissdpc.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/miniupnpc_declspec.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/miniupnpctypes.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/miniwget.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/minixml.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/portlistingparse.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/receivedata.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/upnpcommands.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/upnperrors.h create mode 100644 ext/bin/miniupnpc/include/miniupnpc/upnpreplyparse.h create mode 100644 ext/bin/miniupnpc/mac-x64/libminiupnpc.a diff --git a/ext/bin/miniupnpc/Changelog.txt b/ext/bin/miniupnpc/Changelog.txt new file mode 100644 index 000000000..bb2abb7ee --- /dev/null +++ b/ext/bin/miniupnpc/Changelog.txt @@ -0,0 +1,633 @@ +$Id: Changelog.txt,v 1.208 2015/07/15 12:18:59 nanard Exp $ +miniUPnP client Changelog. + +2015/07/15: + Check malloc/calloc + +2015/06/16: + update getDevicesFromMiniSSDPD() to process longer minissdpd + responses + +2015/05/22: + add searchalltypes param to upnpDiscoverDevices() + increments API_VERSION to 13 + +2015/04/30: + upnpc: output version on the terminal + +2015/04/27: + _BSD_SOURCE is deprecated in favor of _DEFAULT_SOURCE + fix CMakeLists.txt COMPILE_DEFINITIONS + fix getDevicesFromMiniSSDPD() not setting scope_id + improve -r command of upnpc command line tool + +2014/11/17: + search all : + upnpDiscoverDevices() / upnpDiscoverAll() functions + listdevices executable + increment API_VERSION to 12 + validate igd_desc_parse + +2014/11/13: + increment API_VERSION to 11 + +2014/11/05: + simplified function GetUPNPUrls() + +2014/09/11: + use remoteHost arg of DeletePortMapping + +2014/09/06: + Fix python3 build + +2014/07/01: + Fix parsing of IGD2 root descriptions + +2014/06/10: + rename LIBSPEC to MINIUPNP_LIBSPEC + +2014/05/15: + Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange + +2014/02/05: + handle EINPROGRESS after connect() + +2014/02/03: + minixml now handle XML comments + +VERSION 1.9 : released 2014/01/31 + +2014/01/31: + added argument remoteHost to UPNP_GetSpecificPortMappingEntry() + increment API_VERSION to 10 + +2013/12/09: + --help and -h arguments in upnpc.c + +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 specificaly + change in simpleUPnPcommand to return the buffer (simplification) + +2011/02/06: + Added leaseDuration argument to AddPortMapping() + Starting to implement GetListOfPortMappings() + +2011/01/11: + updating wingenminiupnpcstrings.c + +2011/01/04: + improving updateminiupnpcstrings.sh + +VERSION 1.5 : released 2011/01/01 + +2010/12/21: + use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo + +2010/12/11: + Improvements on getHTTPResponse() code. + +2010/12/09: + new code for miniwget that handle Chunked transfer encoding + using getHTTPResponse() in SOAP call code + Adding MANIFEST.in for 'python setup.py bdist_rpm' + +2010/11/25: + changes to minissdpc.c to compile under Win32. + see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729 + +2010/09/17: + Various improvement to Makefile from Michał Górny + +2010/08/05: + Adding the script "external-ip.sh" from Reuben Hawkins + +2010/06/09: + update to python module to match modification made on 2010/04/05 + update to Java test code to match modification made on 2010/04/05 + all UPNP_* function now return an error if the SOAP request failed + at HTTP level. + +2010/04/17: + Using GetBestRoute() under win32 in order to find the + right interface to use. + +2010/04/12: + Retrying with HTTP/1.1 if HTTP/1.0 failed. see + http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703 + +2010/04/07: + avoid returning duplicates in upnpDiscover() + +2010/04/05: + Create a connecthostport.h/.c with connecthostport() function + and use it in miniwget and miniupnpc. + Use getnameinfo() instead of inet_ntop or inet_ntoa + Work to make miniupnpc IPV6 compatible... + Add java test code. + Big changes in order to support device having both WANIPConnection + and WANPPPConnection. + +2010/04/04: + Use getaddrinfo() instead of gethostbyname() in miniwget. + +2010/01/06: + #define _DARWIN_C_SOURCE for Mac OS X + +2009/12/19: + Improve MinGW32 build + +2009/12/11: + adding a MSVC9 project to build the static library and executable + +2009/12/10: + Fixing some compilation stuff for Windows/MinGW + +2009/12/07: + adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS + some fixes for Windows when using virtual ethernet adapters (it is the + case with VMWare installed). + +2009/12/04: + some fixes for AmigaOS compilation + Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked + transfer encoding) + +2009/12/03: + updating printIDG and testigddescparse.c for debug. + modifications to compile under AmigaOS + adding a testminiwget program + Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked + transfer encoding + +2009/11/26: + fixing updateminiupnpcstrings.sh to take into account + which command that does not return an error code. + +VERSION 1.4 : released 2009/10/30 + +2009/10/16: + using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module. + +2009/10/10: + Some fixes for compilation under Solaris + compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464 + +2009/09/21: + fixing the code to ignore EINTR during connect() calls. + +2009/08/07: + Set socket timeout for connect() + Some cleanup in miniwget.c + +2009/08/04: + remove multiple redirections with -d in upnpc.c + Print textual error code in upnpc.c + Ignore EINTR during the connect() and poll() calls. + +2009/07/29: + fix in updateminiupnpcstrings.sh if OS name contains "/" + Sending a correct value for MX: field in SSDP request + +2009/07/20: + Change the Makefile to compile under Mac OS X + Fixed a stackoverflow in getDevicesFromMiniSSDPD() + +2009/07/09: + Compile under Haiku + generate miniupnpcstrings.h.in from miniupnpcstrings.h + +2009/06/04: + patching to compile under CygWin and cross compile for minGW + +VERSION 1.3 : + +2009/04/17: + updating python module + Use strtoull() when using C99 + +2009/02/28: + Fixed miniwget.c for compiling under sun + +2008/12/18: + cleanup in Makefile (thanks to Paul de Weerd) + minissdpc.c : win32 compatibility + miniupnpc.c : changed xmlns prefix from 'm' to 'u' + Removed NDEBUG (using DEBUG) + +2008/10/14: + Added the ExternalHost argument to DeletePortMapping() + +2008/10/11: + Added the ExternalHost argument to AddPortMapping() + Put a correct User-Agent: header in HTTP requests. + +VERSION 1.2 : + +2008/10/07: + Update docs + +2008/09/25: + Integrated sameport patch from Dario Meloni : Added a "sameport" + argument to upnpDiscover(). + +2008/07/18: + small modif to make Clang happy :) + +2008/07/17: + #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV... + +2008/07/14: + include declspec.h in installation (to /usr/include/miniupnpc) + +VERSION 1.1 : + +2008/07/04: + standard options for install/ln instead of gnu-specific stuff. + +2008/07/03: + now builds a .dll and .lib with win32. (mingw32) + +2008/04/28: + make install now install the binary of the upnpc tool + +2008/04/27: + added testupnpigd.py + added error strings for miniupnpc "internal" errors + improved python module error/exception reporting. + +2008/04/23: + Completely rewrite igd_desc_parse.c in order to be compatible with + Linksys WAG200G + Added testigddescparse + updated python module + +VERSION 1.0 : + +2008/02/21: + put some #ifdef DEBUG around DisplayNameValueList() + +2008/02/18: + Improved error reporting in upnpcommands.c + UPNP_GetStatusInfo() returns LastConnectionError + +2008/02/16: + better error handling in minisoap.c + improving display of "valid IGD found" in upnpc.c + +2008/02/03: + Fixing UPNP_GetValidIGD() + improved make install :) + +2007/12/22: + Adding upnperrors.c/h to provide a strupnperror() function + used to translate UPnP error codes to string. + +2007/12/19: + Fixing getDevicesFromMiniSSDPD() + improved error reporting of UPnP functions + +2007/12/18: + It is now possible to specify a different location for MiniSSDPd socket. + working with MiniSSDPd is now more efficient. + python module improved. + +2007/12/16: + improving error reporting + +2007/12/13: + Try to improve compatibility by using HTTP/1.0 instead of 1.1 and + XML a bit different for SOAP. + +2007/11/25: + fixed select() call for linux + +2007/11/15: + Added -fPIC to CFLAG for better shared library code. + +2007/11/02: + Fixed a potential socket leak in miniwget2() + +2007/10/16: + added a parameter to upnpDiscover() in order to allow the use of another + interface than the default multicast interface. + +2007/10/12: + Fixed the creation of symbolic link in Makefile + +2007/10/08: + Added man page + +2007/10/02: + fixed memory bug in GetUPNPUrls() + +2007/10/01: + fixes in the Makefile + Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly. + Added SONAME in the shared library to please debian :) + fixed MS Windows compilation (minissdpd is not available under MS Windows). + +2007/09/25: + small change to Makefile to be able to install in a different location + (default is /usr) + +2007/09/24: + now compiling both shared and static library + +2007/09/19: + Cosmetic changes on upnpc.c + +2007/09/02: + adapting to new miniSSDPd (release version ?) + +2007/08/31: + Usage of miniSSDPd to skip discovery process. + +2007/08/27: + fixed python module to allow compilation with Python older than Python 2.4 + +2007/06/12: + Added a python module. + +2007/05/19: + Fixed compilation under MinGW + +2007/05/15: + fixed a memory leak in AddPortMapping() + Added testupnpreplyparse executable to check the parsing of + upnp soap messages + minixml now ignore namespace prefixes. + +2007/04/26: + upnpc now displays external ip address with -s or -l + +2007/04/11: + changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210" + +2007/03/19: + cleanup in miniwget.c + +2007/03/01: + Small typo fix... + +2007/01/30: + Now parsing the HTTP header from SOAP responses in order to + get content-length value. + +2007/01/29: + Fixed the Soap Query to speedup the HTTP request. + added some Win32 DLL stuff... + +2007/01/27: + Fixed some WIN32 compatibility issues + +2006/12/14: + Added UPNPIGD_IsConnected() function in miniupnp.c/.h + Added UPNP_GetValidIGD() in miniupnp.c/.h + cleaned upnpc.c main(). now using UPNP_GetValidIGD() + +2006/12/07: + Version 1.0-RC1 released + +2006/12/03: + Minor changes to compile under SunOS/Solaris + +2006/11/30: + made a minixml parser validator program + updated minixml to handle attributes correctly + +2006/11/22: + Added a -r option to the upnpc sample thanks to Alexander Hubmann. + +2006/11/19: + Cleanup code to make it more ANSI C compliant + +2006/11/10: + detect and display local lan address. + +2006/11/04: + Packets and Bytes Sent/Received are now unsigned int. + +2006/11/01: + Bug fix thanks to Giuseppe D'Angelo + +2006/10/31: + C++ compatibility for .h files. + Added a way to get ip Address on the LAN used to reach the IGD. + +2006/10/25: + Added M-SEARCH to the services in the discovery process. + +2006/10/22: + updated the Makefile to use makedepend, added a "make install" + update Makefile + +2006/10/20: + fixing the description url parsing thanks to patch sent by + Wayne Dawe. + Fixed/translated some comments. + Implemented a better discover process, first looking + for IGD then for root devices (as some devices only reply to + M-SEARCH for root devices). + +2006/09/02: + added freeUPNPDevlist() function. + +2006/08/04: + More command line arguments checking + +2006/08/01: + Added the .bat file to compile under Win32 with minGW32 + +2006/07/31: + Fixed the rootdesc parser (igd_desc_parse.c) + +2006/07/20: + parseMSEARCHReply() is now returning the ST: line as well + starting changes to detect several UPnP devices on the network + +2006/07/19: + using GetCommonLinkProperties to get down/upload bitrate + diff --git a/ext/bin/miniupnpc/LICENSE b/ext/bin/miniupnpc/LICENSE new file mode 100644 index 000000000..cb5a06044 --- /dev/null +++ b/ext/bin/miniupnpc/LICENSE @@ -0,0 +1,27 @@ +MiniUPnPc +Copyright (c) 2005-2015, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/ext/bin/miniupnpc/README.md b/ext/bin/miniupnpc/README.md new file mode 100644 index 000000000..c3d538ba9 --- /dev/null +++ b/ext/bin/miniupnpc/README.md @@ -0,0 +1,4 @@ +libminiupnpc binaries +====== + +This is a binary build of [libminiupnpc](http://miniupnp.free.fr) for certain architectures to faciliate easy building. Where possible the build flags were set for improved security by enabling options like stack protector (a.k.a. stack canary), ASLR support, etc. diff --git a/ext/bin/miniupnpc/VERSION b/ext/bin/miniupnpc/VERSION new file mode 100644 index 000000000..2e0e38c63 --- /dev/null +++ b/ext/bin/miniupnpc/VERSION @@ -0,0 +1 @@ +1.9 diff --git a/ext/bin/miniupnpc/include/miniupnpc/codelength.h b/ext/bin/miniupnpc/include/miniupnpc/codelength.h new file mode 100644 index 000000000..f5f8e30f9 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/codelength.h @@ -0,0 +1,54 @@ +/* $Id: codelength.h,v 1.5 2015/07/09 12:40:18 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas BERNARD + * copyright (c) 2005-2015 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +#ifndef CODELENGTH_H_INCLUDED +#define CODELENGTH_H_INCLUDED + +/* Encode length by using 7bit per Byte : + * Most significant bit of each byte specifies that the + * following byte is part of the code */ + +/* n : unsigned + * p : unsigned char * + */ +#define DECODELENGTH(n, p) n = 0; \ + do { n = (n << 7) | (*p & 0x7f); } \ + while((*(p++)&0x80) && (n<(1<<25))); + +/* n : unsigned + * READ : function/macro to read one byte (unsigned char) + */ +#define DECODELENGTH_READ(n, READ) \ + n = 0; \ + do { \ + unsigned char c; \ + READ(c); \ + n = (n << 7) | (c & 0x07f); \ + if(!(c&0x80)) break; \ + } while(n<(1<<25)); + +/* n : unsigned + * p : unsigned char * + * p_limit : unsigned char * + */ +#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))); + + +/* n : unsigned + * p : unsigned char * + */ +#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ + if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ + if(n>=16384) *(p++) = (n >> 14) | 0x80; \ + if(n>=128) *(p++) = (n >> 7) | 0x80; \ + *(p++) = n & 0x7f; + +#endif /* CODELENGTH_H_INCLUDED */ diff --git a/ext/bin/miniupnpc/include/miniupnpc/connecthostport.h b/ext/bin/miniupnpc/include/miniupnpc/connecthostport.h new file mode 100644 index 000000000..56941d6fa --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/connecthostport.h @@ -0,0 +1,18 @@ +/* $Id: connecthostport.h,v 1.3 2012/09/27 15:42:10 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ + * Author: Thomas Bernard + * Copyright (c) 2010-2012 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef CONNECTHOSTPORT_H_INCLUDED +#define CONNECTHOSTPORT_H_INCLUDED + +/* connecthostport() + * return a socket connected (TCP) to the host and port + * or -1 in case of error */ +int connecthostport(const char * host, unsigned short port, + unsigned int scope_id); + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/igd_desc_parse.h b/ext/bin/miniupnpc/include/miniupnpc/igd_desc_parse.h new file mode 100644 index 000000000..0de546b69 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/igd_desc_parse.h @@ -0,0 +1,49 @@ +/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */ +/* Project : miniupnp + * http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005-2014 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#ifndef IGD_DESC_PARSE_H_INCLUDED +#define IGD_DESC_PARSE_H_INCLUDED + +/* Structure to store the result of the parsing of UPnP + * descriptions of Internet Gateway Devices */ +#define MINIUPNPC_URL_MAXSIZE (128) +struct IGDdatas_service { + char controlurl[MINIUPNPC_URL_MAXSIZE]; + char eventsuburl[MINIUPNPC_URL_MAXSIZE]; + char scpdurl[MINIUPNPC_URL_MAXSIZE]; + char servicetype[MINIUPNPC_URL_MAXSIZE]; + /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/ +}; + +struct IGDdatas { + char cureltname[MINIUPNPC_URL_MAXSIZE]; + char urlbase[MINIUPNPC_URL_MAXSIZE]; + char presentationurl[MINIUPNPC_URL_MAXSIZE]; + int level; + /*int state;*/ + /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ + struct IGDdatas_service CIF; + /* "urn:schemas-upnp-org:service:WANIPConnection:1" + * "urn:schemas-upnp-org:service:WANPPPConnection:1" */ + struct IGDdatas_service first; + /* if both WANIPConnection and WANPPPConnection are present */ + struct IGDdatas_service second; + /* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */ + struct IGDdatas_service IPv6FC; + /* tmp */ + struct IGDdatas_service tmp; +}; + +void IGDstartelt(void *, const char *, int); +void IGDendelt(void *, const char *, int); +void IGDdata(void *, const char *, int); +#ifdef DEBUG +void printIGD(struct IGDdatas *); +#endif /* DEBUG */ + +#endif /* IGD_DESC_PARSE_H_INCLUDED */ diff --git a/ext/bin/miniupnpc/include/miniupnpc/minisoap.h b/ext/bin/miniupnpc/include/miniupnpc/minisoap.h new file mode 100644 index 000000000..14c859d1e --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/minisoap.h @@ -0,0 +1,15 @@ +/* $Id: minisoap.h,v 1.5 2012/09/27 15:42:10 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ +#ifndef MINISOAP_H_INCLUDED +#define MINISOAP_H_INCLUDED + +/*int httpWrite(int, const char *, int, const char *);*/ +int soapPostSubmit(int, const char *, const char *, unsigned short, + const char *, const char *, const char *); + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/minissdpc.h b/ext/bin/miniupnpc/include/miniupnpc/minissdpc.h new file mode 100644 index 000000000..915b0026f --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/minissdpc.h @@ -0,0 +1,15 @@ +/* $Id: minissdpc.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2007 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINISSDPC_H_INCLUDED +#define MINISSDPC_H_INCLUDED + +struct UPNPDev * +getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath); + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h new file mode 100644 index 000000000..0eeabc234 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc.h @@ -0,0 +1,154 @@ +/* $Id: miniupnpc.h,v 1.42 2015/07/21 13:16:55 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ + * Author: Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINIUPNPC_H_INCLUDED +#define MINIUPNPC_H_INCLUDED + +#include "miniupnpc_declspec.h" +#include "igd_desc_parse.h" + +/* error codes : */ +#define UPNPDISCOVER_SUCCESS (0) +#define UPNPDISCOVER_UNKNOWN_ERROR (-1) +#define UPNPDISCOVER_SOCKET_ERROR (-101) +#define UPNPDISCOVER_MEMORY_ERROR (-102) + +/* versions : */ +#define MINIUPNPC_VERSION "1.9.20150721" +#define MINIUPNPC_API_VERSION 13 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structures definitions : */ +struct UPNParg { const char * elt; const char * val; }; + +char * +simpleUPnPcommand(int, const char *, const char *, + const char *, struct UPNParg *, + int *); + +struct UPNPDev { + struct UPNPDev * pNext; + char * descURL; + char * st; + unsigned int scope_id; + char buffer[2]; +}; + +/* upnpDiscover() + * discover UPnP devices on the network. + * The discovered devices are returned as a chained list. + * It is up to the caller to free the list with freeUPNPDevlist(). + * delay (in millisecond) is the maximum time for waiting any device + * response. + * If available, device list will be obtained from MiniSSDPd. + * Default path for minissdpd socket will be used if minissdpdsock argument + * is NULL. + * If multicastif is not NULL, it will be used instead of the default + * multicast interface for sending SSDP discover packets. + * If sameport is not null, SSDP packets will be sent from the source port + * 1900 (same as destination port) otherwise system assign a source port. + * "searchalltypes" parameter is useful when searching several types, + * if 0, the discovery will stop with the first type returning results. */ +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock, int sameport, + int ipv6, + int * error); + +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverAll(int delay, const char * multicastif, + const char * minissdpdsock, int sameport, + int ipv6, + int * error); + +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverDevice(const char * device, int delay, const char * multicastif, + const char * minissdpdsock, int sameport, + int ipv6, + int * error); + +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverDevices(const char * const deviceTypes[], + int delay, const char * multicastif, + const char * minissdpdsock, int sameport, + int ipv6, + int * error, + int searchalltypes); + +/* freeUPNPDevlist() + * free list returned by upnpDiscover() */ +MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); + +/* parserootdesc() : + * parse root XML description of a UPnP device and fill the IGDdatas + * structure. */ +MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *); + +/* structure used to get fast access to urls + * controlURL: controlURL of the WANIPConnection + * ipcondescURL: url of the description of the WANIPConnection + * controlURL_CIF: controlURL of the WANCommonInterfaceConfig + * controlURL_6FC: controlURL of the WANIPv6FirewallControl + */ +struct UPNPUrls { + char * controlURL; + char * ipcondescURL; + char * controlURL_CIF; + char * controlURL_6FC; + char * rootdescURL; +}; + +/* UPNP_GetValidIGD() : + * return values : + * 0 = NO IGD found + * 1 = A valid connected IGD has been found + * 2 = A valid IGD has been found but it reported as + * not connected + * 3 = an UPnP device has been found but was not recognized as an IGD + * + * In any non zero return case, the urls and data structures + * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to + * free allocated memory. + */ +MINIUPNP_LIBSPEC int +UPNP_GetValidIGD(struct UPNPDev * devlist, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen); + +/* UPNP_GetIGDFromUrl() + * Used when skipping the discovery process. + * When succeding, urls, data, and lanaddr arguments are set. + * return value : + * 0 - Not ok + * 1 - OK */ +MINIUPNP_LIBSPEC int +UPNP_GetIGDFromUrl(const char * rootdescurl, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen); + +MINIUPNP_LIBSPEC void +GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, + const char *, unsigned int); + +MINIUPNP_LIBSPEC void +FreeUPNPUrls(struct UPNPUrls *); + +/* return 0 or 1 */ +MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/miniupnpc_declspec.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc_declspec.h new file mode 100644 index 000000000..40adb922e --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/miniupnpc_declspec.h @@ -0,0 +1,21 @@ +#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED +#define MINIUPNPC_DECLSPEC_H_INCLUDED + +#if defined(_WIN32) && !defined(MINIUPNP_STATICLIB) + /* for windows dll */ + #ifdef MINIUPNP_EXPORTS + #define MINIUPNP_LIBSPEC __declspec(dllexport) + #else + #define MINIUPNP_LIBSPEC __declspec(dllimport) + #endif +#else + #if defined(__GNUC__) && __GNUC__ >= 4 + /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */ + #define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default"))) + #else + #define MINIUPNP_LIBSPEC + #endif +#endif + +#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */ + diff --git a/ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h new file mode 100644 index 000000000..80a1d757d --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/miniupnpcstrings.h @@ -0,0 +1,23 @@ +/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2014 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINIUPNPCSTRINGS_H_INCLUDED +#define MINIUPNPCSTRINGS_H_INCLUDED + +#define OS_STRING "Darwin/14.4.0" +#define MINIUPNPC_VERSION_STRING "1.9" + +#if 0 +/* according to "UPnP Device Architecture 1.0" */ +#define UPNP_VERSION_STRING "UPnP/1.0" +#else +/* according to "UPnP Device Architecture 1.1" */ +#define UPNP_VERSION_STRING "UPnP/1.1" +#endif + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/miniupnpctypes.h b/ext/bin/miniupnpc/include/miniupnpc/miniupnpctypes.h new file mode 100644 index 000000000..591c32fb6 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/miniupnpctypes.h @@ -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 + diff --git a/ext/bin/miniupnpc/include/miniupnpc/miniwget.h b/ext/bin/miniupnpc/include/miniupnpc/miniwget.h new file mode 100644 index 000000000..d6db71a85 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/miniwget.h @@ -0,0 +1,30 @@ +/* $Id: miniwget.h,v 1.10 2015/07/21 13:16:55 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#ifndef MINIWGET_H_INCLUDED +#define MINIWGET_H_INCLUDED + +#include "miniupnpc_declspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size); + +MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int); + +MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int); + +int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/minixml.h b/ext/bin/miniupnpc/include/miniupnpc/minixml.h new file mode 100644 index 000000000..9f43aa48c --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/minixml.h @@ -0,0 +1,37 @@ +/* $Id: minixml.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */ +/* minimal xml parser + * + * Project : miniupnp + * Website : http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#ifndef MINIXML_H_INCLUDED +#define MINIXML_H_INCLUDED +#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) + +/* if a callback function pointer is set to NULL, + * the function is not called */ +struct xmlparser { + const char *xmlstart; + const char *xmlend; + const char *xml; /* pointer to current character */ + int xmlsize; + void * data; + void (*starteltfunc) (void *, const char *, int); + void (*endeltfunc) (void *, const char *, int); + void (*datafunc) (void *, const char *, int); + void (*attfunc) (void *, const char *, int, const char *, int); +}; + +/* parsexml() + * the xmlparser structure must be initialized before the call + * the following structure members have to be initialized : + * xmlstart, xmlsize, data, *func + * xml is for internal usage, xmlend is computed automatically */ +void parsexml(struct xmlparser *); + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/portlistingparse.h b/ext/bin/miniupnpc/include/miniupnpc/portlistingparse.h new file mode 100644 index 000000000..661ad1faa --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/portlistingparse.h @@ -0,0 +1,65 @@ +/* $Id: portlistingparse.h,v 1.11 2015/07/21 13:16:55 nanard Exp $ */ +/* MiniUPnP project + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * (c) 2011-2015 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 "miniupnpc_declspec.h" +/* for the definition of UNSIGNED_INTEGER */ +#include "miniupnpctypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* sample of PortMappingEntry : + + 202.233.2.1 + 2345 + TCP + 2345 + 192.168.1.137 + 1 + dooom + 345 + + */ +typedef enum { PortMappingEltNone, + PortMappingEntry, NewRemoteHost, + NewExternalPort, NewProtocol, + NewInternalPort, NewInternalClient, + NewEnabled, NewDescription, + NewLeaseTime } portMappingElt; + +struct PortMapping { + struct PortMapping * l_next; /* list next element */ + 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 { + struct PortMapping * l_head; /* list head */ + portMappingElt curelt; +}; + +MINIUPNP_LIBSPEC void +ParsePortListing(const char * buffer, int bufsize, + struct PortMappingParserData * pdata); + +MINIUPNP_LIBSPEC void +FreePortListing(struct PortMappingParserData * pdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/bin/miniupnpc/include/miniupnpc/receivedata.h b/ext/bin/miniupnpc/include/miniupnpc/receivedata.h new file mode 100644 index 000000000..0520a11d3 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/receivedata.h @@ -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 + diff --git a/ext/bin/miniupnpc/include/miniupnpc/upnpcommands.h b/ext/bin/miniupnpc/include/miniupnpc/upnpcommands.h new file mode 100644 index 000000000..22eda5e39 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/upnpcommands.h @@ -0,0 +1,348 @@ +/* $Id: upnpcommands.h,v 1.31 2015/07/21 13:16:55 nanard Exp $ */ +/* Miniupnp project : http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided within this distribution */ +#ifndef UPNPCOMMANDS_H_INCLUDED +#define UPNPCOMMANDS_H_INCLUDED + +#include "upnpreplyparse.h" +#include "portlistingparse.h" +#include "miniupnpc_declspec.h" +#include "miniupnpctypes.h" + +/* MiniUPnPc return codes : */ +#define UPNPCOMMAND_SUCCESS (0) +#define UPNPCOMMAND_UNKNOWN_ERROR (-1) +#define UPNPCOMMAND_INVALID_ARGS (-2) +#define UPNPCOMMAND_HTTP_ERROR (-3) +#define UPNPCOMMAND_INVALID_RESPONSE (-4) +#define UPNPCOMMAND_MEM_ALLOC_ERROR (-5) + +#ifdef __cplusplus +extern "C" { +#endif + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalBytesSent(const char * controlURL, + const char * servicetype); + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalBytesReceived(const char * controlURL, + const char * servicetype); + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalPacketsSent(const char * controlURL, + const char * servicetype); + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalPacketsReceived(const char * controlURL, + const char * servicetype); + +/* UPNP_GetStatusInfo() + * status and lastconnerror are 64 byte buffers + * Return values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error code */ +MINIUPNP_LIBSPEC int +UPNP_GetStatusInfo(const char * controlURL, + const char * servicetype, + char * status, + unsigned int * uptime, + char * lastconnerror); + +/* UPNP_GetConnectionTypeInfo() + * argument connectionType is a 64 character buffer + * Return Values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error code */ +MINIUPNP_LIBSPEC int +UPNP_GetConnectionTypeInfo(const char * controlURL, + const char * servicetype, + char * connectionType); + +/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. + * if the third arg is not null the value is copied to it. + * at least 16 bytes must be available + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR Either an UPnP error code or an unknown error. + * + * possible UPnP Errors : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. */ +MINIUPNP_LIBSPEC int +UPNP_GetExternalIPAddress(const char * controlURL, + const char * servicetype, + char * extIpAdd); + +/* UPNP_GetLinkLayerMaxBitRates() + * call WANCommonInterfaceConfig:1#GetCommonLinkProperties + * + * return values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. */ +MINIUPNP_LIBSPEC int +UPNP_GetLinkLayerMaxBitRates(const char* controlURL, + const char* servicetype, + unsigned int * bitrateDown, + unsigned int * bitrateUp); + +/* UPNP_AddPortMapping() + * if desc is NULL, it will be defaulted to "libminiupnpc" + * remoteHost is usually NULL because IGD don't support it. + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR. Either an UPnP error code or an unknown error. + * + * List of possible UPnP errors for AddPortMapping : + * errorCode errorDescription (short) - Description (long) + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization and + * the sender was not authorized. + * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be + * wild-carded + * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded + * 718 ConflictInMappingEntry - The port mapping entry specified conflicts + * with a mapping assigned previously to another client + * 724 SamePortValuesRequired - Internal and External port values + * must be the same + * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports + * permanent lease times on port mappings + * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard + * and cannot be a specific IP address or DNS name + * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and + * cannot be a specific port value + * 728 NoPortMapsAvailable - There are not enough free ports available to + * complete port mapping. + * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed + * due to conflict with other mechanisms. + * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded + */ +MINIUPNP_LIBSPEC int +UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration); + +/* UPNP_AddAnyPortMapping() + * if desc is NULL, it will be defaulted to "libminiupnpc" + * remoteHost is usually NULL because IGD don't support it. + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR. Either an UPnP error code or an unknown error. + * + * List of possible UPnP errors for AddPortMapping : + * errorCode errorDescription (short) - Description (long) + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization and + * the sender was not authorized. + * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be + * wild-carded + * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded + * 728 NoPortMapsAvailable - There are not enough free ports available to + * complete port mapping. + * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed + * due to conflict with other mechanisms. + * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded + */ +MINIUPNP_LIBSPEC int +UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration, + char * reservedPort); + +/* UPNP_DeletePortMapping() + * Use same argument values as what was used for AddPortMapping(). + * remoteHost is usually NULL because IGD don't support it. + * Return Values : + * 0 : SUCCESS + * NON ZERO : error. Either an UPnP error code or an undefined error. + * + * List of possible UPnP errors for DeletePortMapping : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 714 NoSuchEntryInArray - The specified value does not exist in the array */ +MINIUPNP_LIBSPEC int +UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, + const char * extPort, const char * proto, + const char * remoteHost); + +/* UPNP_DeletePortRangeMapping() + * Use same argument values as what was used for AddPortMapping(). + * remoteHost is usually NULL because IGD don't support it. + * Return Values : + * 0 : SUCCESS + * NON ZERO : error. Either an UPnP error code or an undefined error. + * + * List of possible UPnP errors for DeletePortMapping : + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 730 PortMappingNotFound - This error message is returned if no port + * mapping is found in the specified range. + * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */ +MINIUPNP_LIBSPEC int +UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, + const char * extPortStart, const char * extPortEnd, + const char * proto, + const char * manage); + +/* UPNP_GetPortMappingNumberOfEntries() + * not supported by all routers */ +MINIUPNP_LIBSPEC int +UPNP_GetPortMappingNumberOfEntries(const char* controlURL, + const char* servicetype, + unsigned int * num); + +/* UPNP_GetSpecificPortMappingEntry() + * retrieves an existing port mapping + * params : + * in extPort + * in proto + * in remoteHost + * out intClient (16 bytes) + * out intPort (6 bytes) + * out desc (80 bytes) + * out enabled (4 bytes) + * out leaseDuration (16 bytes) + * + * return value : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. + * + * List of possible UPnP errors for _GetSpecificPortMappingEntry : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 714 NoSuchEntryInArray - The specified value does not exist in the array. + */ +MINIUPNP_LIBSPEC int +UPNP_GetSpecificPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * extPort, + const char * proto, + const char * remoteHost, + char * intClient, + char * intPort, + char * desc, + char * enabled, + char * leaseDuration); + +/* UPNP_GetGenericPortMappingEntry() + * params : + * in index + * out extPort (6 bytes) + * out intClient (16 bytes) + * out intPort (6 bytes) + * out protocol (4 bytes) + * out desc (80 bytes) + * out enabled (4 bytes) + * out rHost (64 bytes) + * out duration (16 bytes) + * + * return value : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. + * + * Possible UPNP Error codes : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds + */ +MINIUPNP_LIBSPEC int +UPNP_GetGenericPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * index, + char * extPort, + char * intClient, + char * intPort, + char * protocol, + char * desc, + char * enabled, + char * rHost, + char * duration); + +/* UPNP_GetListOfPortMappings() Available in IGD v2 + * + * + * Possible UPNP Error codes : + * 606 Action not Authorized + * 730 PortMappingNotFound - no port mapping is found in the specified range. + * 733 InconsistantParameters - NewStartPort and NewEndPort values are not + * consistent. + */ +MINIUPNP_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 */ +MINIUPNP_LIBSPEC int +UPNP_GetFirewallStatus(const char * controlURL, + const char * servicetype, + int * firewallEnabled, + int * inboundPinholeAllowed); + +MINIUPNP_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); + +MINIUPNP_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); + +MINIUPNP_LIBSPEC int +UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, + const char * uniqueID, + const char * leaseTime); + +MINIUPNP_LIBSPEC int +UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID); + +MINIUPNP_LIBSPEC int +UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, + const char * uniqueID, int * isWorking); + +MINIUPNP_LIBSPEC int +UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, + const char * uniqueID, int * packets); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ext/bin/miniupnpc/include/miniupnpc/upnperrors.h b/ext/bin/miniupnpc/include/miniupnpc/upnperrors.h new file mode 100644 index 000000000..3115aee5b --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/upnperrors.h @@ -0,0 +1,26 @@ +/* $Id: upnperrors.h,v 1.6 2015/07/21 13:16:55 nanard Exp $ */ +/* (c) 2007-2015 Thomas Bernard + * All rights reserved. + * MiniUPnP Project. + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +#ifndef UPNPERRORS_H_INCLUDED +#define UPNPERRORS_H_INCLUDED + +#include "miniupnpc_declspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* strupnperror() + * Return a string description of the UPnP error code + * or NULL for undefinded errors */ +MINIUPNP_LIBSPEC const char * strupnperror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/bin/miniupnpc/include/miniupnpc/upnpreplyparse.h b/ext/bin/miniupnpc/include/miniupnpc/upnpreplyparse.h new file mode 100644 index 000000000..6badd15b2 --- /dev/null +++ b/ext/bin/miniupnpc/include/miniupnpc/upnpreplyparse.h @@ -0,0 +1,63 @@ +/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */ +/* MiniUPnP project + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * (c) 2006-2013 Thomas Bernard + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ + +#ifndef UPNPREPLYPARSE_H_INCLUDED +#define UPNPREPLYPARSE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +struct NameValue { + struct NameValue * l_next; + char name[64]; + char value[128]; +}; + +struct NameValueParserData { + struct NameValue * l_head; + char curelt[64]; + char * portListing; + int portListingLength; + int topelt; + const char * cdata; + int cdatalen; +}; + +/* ParseNameValue() */ +void +ParseNameValue(const char * buffer, int bufsize, + struct NameValueParserData * data); + +/* ClearNameValueList() */ +void +ClearNameValueList(struct NameValueParserData * pdata); + +/* GetValueFromNameValueList() */ +char * +GetValueFromNameValueList(struct NameValueParserData * pdata, + const char * Name); + +#if 0 +/* GetValueFromNameValueListIgnoreNS() */ +char * +GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, + const char * Name); +#endif + +/* DisplayNameValueList() */ +#ifdef DEBUG +void +DisplayNameValueList(char * buffer, int bufsize); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ext/bin/miniupnpc/mac-x64/libminiupnpc.a b/ext/bin/miniupnpc/mac-x64/libminiupnpc.a new file mode 100644 index 0000000000000000000000000000000000000000..3c2e528d1d462f057e9edfeb824fd2a5e54c3002 GIT binary patch literal 95616 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 HH01R^+(s$* literal 0 HcmV?d00001 diff --git a/make-mac.mk b/make-mac.mk index 55b117e6f..707d517cc 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -5,7 +5,7 @@ ifeq ($(origin CXX),default) CXX=$(shell if [ -e /usr/bin/clang++ ]; then echo clang++; else echo g++; fi) endif -INCLUDES=-I/usr/local/include +INCLUDES= DEFS= LIBS= ARCH_FLAGS=-arch x86_64 @@ -13,6 +13,9 @@ ARCH_FLAGS=-arch x86_64 include objects.mk OBJS+=osdep/OSXEthernetTap.o +# Comment out to disable building against shipped libminiupnpc binary for Mac +ZT_USE_MINIUPNPC=1 + # Disable codesign since open source users will not have ZeroTier's certs CODESIGN=echo PRODUCTSIGN=echo @@ -35,7 +38,8 @@ endif ifeq ($(ZT_USE_MINIUPNPC),1) DEFS+=-DZT_USE_MINIUPNPC - LIBS+=/usr/local/lib/libminiupnpc.a + INCLUDES+=-Iext/bin/miniupnpc/include + LIBS+=ext/bin/miniupnpc/mac-x64/libminiupnpc.a OBJS+=osdep/UPNPClient.o endif diff --git a/service/OneService.cpp b/service/OneService.cpp index 05fdfb905..06e37a45f 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -584,10 +584,8 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient.get()); - for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) { - printf("Adding UPNP address: %s\n",ext->toString().c_str()); + for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),0,ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); - } #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0;