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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 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;