mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-08 07:07:05 +02:00
* Updated miniupnp and added blocked devices support to libportfwd.
This commit is contained in:
7
thirdparty/libportfwd/CMakeLists.txt
vendored
7
thirdparty/libportfwd/CMakeLists.txt
vendored
@@ -3,8 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
|
|||||||
SET(CMAKE_VERBOSE_MAKEFILE ON)
|
SET(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
#SET(CMAKE_INSTALL_PREFIX ".")
|
#SET(CMAKE_INSTALL_PREFIX ".")
|
||||||
|
|
||||||
SET(MINIUPNP_DIR "third-party/miniupnpc-1.4.20100609/")
|
SET(MINIUPNP_DIR "third-party/miniupnpc-1.6/")
|
||||||
SET(NATPMP_DIR "third-party/libnatpmp-20100202")
|
SET(NATPMP_DIR "third-party/libnatpmp-20100808")
|
||||||
|
|
||||||
ADD_DEFINITIONS(-Wall -O2 -DNDEBUG)
|
ADD_DEFINITIONS(-Wall -O2 -DNDEBUG)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
@@ -27,6 +27,9 @@ ADD_LIBRARY(tomahawk_portfwd SHARED
|
|||||||
${MINIUPNP_DIR}/miniupnpc.c
|
${MINIUPNP_DIR}/miniupnpc.c
|
||||||
${MINIUPNP_DIR}/miniwget.c
|
${MINIUPNP_DIR}/miniwget.c
|
||||||
${MINIUPNP_DIR}/minixml.c
|
${MINIUPNP_DIR}/minixml.c
|
||||||
|
${MINIUPNP_DIR}/minixmlvalid.c
|
||||||
|
${MINIUPNP_DIR}/portlistingparse.c
|
||||||
|
${MINIUPNP_DIR}/receivedata.c
|
||||||
#${MINIUPNP_DIR}/minixmlvalid.c - contains main() like upnp.c, so building a shared lib fails
|
#${MINIUPNP_DIR}/minixmlvalid.c - contains main() like upnp.c, so building a shared lib fails
|
||||||
#${MINIUPNP_DIR}/upnpc.c
|
#${MINIUPNP_DIR}/upnpc.c
|
||||||
${MINIUPNP_DIR}/upnpcommands.c
|
${MINIUPNP_DIR}/upnpcommands.c
|
||||||
|
30
thirdparty/libportfwd/include/portfwd/portfwd.h
vendored
30
thirdparty/libportfwd/include/portfwd/portfwd.h
vendored
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBPORTFWD_PORTFWD_H
|
#ifndef LIBPORTFWD_PORTFWD_H
|
||||||
#define LIBPORTFWD_PORTFWD_H true
|
#define LIBPORTFWD_PORTFWD_H
|
||||||
|
|
||||||
#include "portfwddllmacro.h"
|
#include "portfwddllmacro.h"
|
||||||
|
|
||||||
@@ -24,8 +24,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
//fwd:
|
|
||||||
struct UPNPUrls;
|
struct UPNPUrls;
|
||||||
struct IGDdatas;
|
struct IGDdatas;
|
||||||
|
|
||||||
@@ -34,24 +35,27 @@ class PORTFWDDLLEXPORT Portfwd
|
|||||||
public:
|
public:
|
||||||
Portfwd();
|
Portfwd();
|
||||||
~Portfwd();
|
~Portfwd();
|
||||||
|
|
||||||
/// timeout: milliseconds to wait for a router to respond
|
/// timeout: milliseconds to wait for a router to respond
|
||||||
/// 2000 is typically enough.
|
/// 2000 is typically enough.
|
||||||
bool init(unsigned int timeout);
|
bool init( unsigned int timeout );
|
||||||
void get_status();
|
void get_status();
|
||||||
bool add(unsigned short port, unsigned short internal_port );
|
|
||||||
bool remove(unsigned short port);
|
bool add( unsigned short port, unsigned short internal_port );
|
||||||
|
bool remove( unsigned short port );
|
||||||
const std::string& external_ip() const
|
|
||||||
{ return m_externalip; }
|
void addBlockedDevice( const std::string& ip );
|
||||||
const std::string& lan_ip() const
|
|
||||||
{ return m_lanip; }
|
const std::string& external_ip() const { return m_externalip; }
|
||||||
|
const std::string& lan_ip() const { return m_lanip; }
|
||||||
unsigned int max_upstream_bps() const { return m_upbps; }
|
unsigned int max_upstream_bps() const { return m_upbps; }
|
||||||
unsigned int max_downstream_bps() const { return m_downbps; }
|
unsigned int max_downstream_bps() const { return m_downbps; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct UPNPUrls* urls;
|
struct UPNPUrls* m_urls;
|
||||||
struct IGDdatas* data;
|
struct IGDdatas* m_data;
|
||||||
|
|
||||||
|
std::list<std::string> m_blockedips;
|
||||||
std::string m_lanip, m_externalip;
|
std::string m_lanip, m_externalip;
|
||||||
unsigned int m_upbps, m_downbps;
|
unsigned int m_upbps, m_downbps;
|
||||||
};
|
};
|
||||||
|
199
thirdparty/libportfwd/src/portfwd.cpp
vendored
199
thirdparty/libportfwd/src/portfwd.cpp
vendored
@@ -22,147 +22,190 @@
|
|||||||
#include "upnpcommands.h"
|
#include "upnpcommands.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include "../include/portfwd/portfwd.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Portfwd::Portfwd()
|
Portfwd::Portfwd()
|
||||||
: urls(0), data(0)
|
: m_urls( 0 )
|
||||||
|
, m_data( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Portfwd::~Portfwd()
|
Portfwd::~Portfwd()
|
||||||
{
|
{
|
||||||
if(urls) free(urls);
|
if ( m_urls )
|
||||||
if(data) free(data);
|
free( m_urls );
|
||||||
|
|
||||||
|
if ( m_data )
|
||||||
|
free( m_data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Portfwd::init(unsigned int timeout)
|
Portfwd::init( unsigned int timeout )
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
int nResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
|
||||||
if(nResult != NO_ERROR)
|
if ( nResult != NO_ERROR )
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WSAStartup() failed.\n");
|
fprintf( stderr, "WSAStartup() failed.\n" );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
struct UPNPDev * devlist;
|
|
||||||
struct UPNPDev * dev;
|
|
||||||
char * descXML;
|
|
||||||
int descXMLsize = 0;
|
|
||||||
printf("Portfwd::init()\n");
|
|
||||||
urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls));
|
|
||||||
data = (IGDdatas*)malloc(sizeof(struct IGDdatas));
|
|
||||||
memset(urls, 0, sizeof(struct UPNPUrls));
|
|
||||||
memset(data, 0, sizeof(struct IGDdatas));
|
|
||||||
devlist = upnpDiscover(timeout, NULL, NULL, 0);
|
|
||||||
if (devlist)
|
|
||||||
{
|
|
||||||
dev = devlist;
|
|
||||||
while (dev)
|
|
||||||
{
|
|
||||||
if (strstr (dev->st, "InternetGatewayDevice"))
|
|
||||||
break;
|
|
||||||
dev = dev->pNext;
|
|
||||||
}
|
|
||||||
if (!dev)
|
|
||||||
dev = devlist; /* defaulting to first device */
|
|
||||||
|
|
||||||
printf("UPnP device :\n"
|
struct UPNPDev* devlist;
|
||||||
" desc: %s\n st: %s\n",
|
struct UPNPDev* dev;
|
||||||
dev->descURL, dev->st);
|
char* descXML;
|
||||||
|
int descXMLsize = 0;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
descXML = (char*)miniwget(dev->descURL, &descXMLsize);
|
printf( "Portfwd::init()\n" );
|
||||||
if (descXML)
|
m_urls = (UPNPUrls*)malloc( sizeof( struct UPNPUrls ) );
|
||||||
|
m_data = (IGDdatas*)malloc( sizeof( struct IGDdatas ) );
|
||||||
|
memset( m_urls, 0, sizeof( struct UPNPUrls ) );
|
||||||
|
memset( m_data, 0, sizeof( struct IGDdatas ) );
|
||||||
|
|
||||||
|
devlist = upnpDiscover( timeout, NULL, NULL, 0, 0, &error );
|
||||||
|
if ( devlist )
|
||||||
|
{
|
||||||
|
dev = devlist;
|
||||||
|
while ( dev )
|
||||||
|
{
|
||||||
|
printf( "descurl: %s\n", dev->descURL );
|
||||||
|
|
||||||
|
bool blocked = false;
|
||||||
|
std::list<std::string>::iterator it;
|
||||||
|
for ( it = m_blockedips.begin(); it != m_blockedips.end(); ++it )
|
||||||
|
{
|
||||||
|
printf( "blocked ip: %s\n", it->c_str() );
|
||||||
|
|
||||||
|
if ( strstr( dev->descURL, it->c_str() ) )
|
||||||
|
{
|
||||||
|
printf( "nope, we blocked this gateway: %s\n", dev->descURL );
|
||||||
|
blocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( blocked )
|
||||||
|
{
|
||||||
|
dev = dev->pNext;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strstr( dev->st, "InternetGatewayDevice" ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
dev = dev->pNext;
|
||||||
|
}
|
||||||
|
if ( !dev )
|
||||||
|
dev = devlist; /* defaulting to first device */
|
||||||
|
|
||||||
|
printf( "UPnP device :\n"
|
||||||
|
" desc: %s\n st: %s\n",
|
||||||
|
dev->descURL, dev->st );
|
||||||
|
|
||||||
|
descXML = (char*)miniwget( dev->descURL, &descXMLsize );
|
||||||
|
if ( descXML )
|
||||||
{
|
{
|
||||||
parserootdesc (descXML, descXMLsize, data);
|
parserootdesc( descXML, descXMLsize, m_data );
|
||||||
free (descXML); descXML = 0;
|
free( descXML );
|
||||||
GetUPNPUrls (urls, data, dev->descURL);
|
descXML = 0;
|
||||||
|
|
||||||
|
GetUPNPUrls( m_urls, m_data, dev->descURL );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("couldn't get the UPnP device description XML (descXML is null)");
|
printf( "couldn't get the UPnP device description XML (descXML is null)" );
|
||||||
freeUPNPDevlist(devlist);
|
freeUPNPDevlist( devlist );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get lan IP:
|
// get lan IP:
|
||||||
char lanaddr[16];
|
char lanaddr[16];
|
||||||
int idg_was_found = UPNP_GetValidIGD(devlist, urls, data, (char*)&lanaddr, 16);
|
int idg_was_found = UPNP_GetValidIGD( devlist, m_urls, m_data, (char*)&lanaddr, 16 );
|
||||||
printf("UPNP_GetValidIGD returned %d", idg_was_found);
|
if ( !idg_was_found )
|
||||||
if (!idg_was_found)
|
|
||||||
{
|
{
|
||||||
printf("NO IGD was found (function UPNP_GetValidIGD())");
|
printf( "NO IGD was found (function UPNP_GetValidIGD())" );
|
||||||
freeUPNPDevlist(devlist);
|
freeUPNPDevlist( devlist );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_lanip = std::string(lanaddr);
|
m_lanip = std::string( lanaddr );
|
||||||
|
|
||||||
freeUPNPDevlist(devlist);
|
freeUPNPDevlist( devlist );
|
||||||
get_status();
|
get_status();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Portfwd::get_status()
|
Portfwd::get_status()
|
||||||
{
|
{
|
||||||
// Q_ASSERT(urls->controlURL_CIF != NULL);
|
|
||||||
// get connection speed
|
// get connection speed
|
||||||
UPNP_GetLinkLayerMaxBitRates(
|
UPNP_GetLinkLayerMaxBitRates( m_urls->controlURL_CIF, m_data->CIF.servicetype, &m_downbps, &m_upbps );
|
||||||
urls->controlURL_CIF, data->CIF.servicetype, &m_downbps, &m_upbps);
|
|
||||||
|
|
||||||
// get external IP adress
|
// get external IP adress
|
||||||
char ip[16];
|
char ip[16];
|
||||||
if( 0 != UPNP_GetExternalIPAddress( urls->controlURL,
|
if ( 0 != UPNP_GetExternalIPAddress( m_urls->controlURL, m_data->CIF.servicetype, (char*)&ip ) )
|
||||||
data->CIF.servicetype,
|
|
||||||
(char*)&ip ) )
|
|
||||||
{
|
{
|
||||||
m_externalip = ""; //failed
|
m_externalip = ""; //failed
|
||||||
}else{
|
}
|
||||||
m_externalip = std::string(ip);
|
else
|
||||||
|
{
|
||||||
|
m_externalip = std::string( ip );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Portfwd::add( unsigned short port, unsigned short internal_port )
|
Portfwd::add( unsigned short port, unsigned short internal_port )
|
||||||
{
|
{
|
||||||
char port_str[16], port_str_internal[16];
|
char port_str[16], port_str_internal[16];
|
||||||
int r;
|
int r;
|
||||||
printf("Portfwd::add (%s, %d)\n", m_lanip.c_str(), port);
|
printf( "Portfwd::add (%s, %d)\n", m_lanip.c_str(), port );
|
||||||
if(urls->controlURL[0] == '\0')
|
if ( m_urls->controlURL[0] == '\0' )
|
||||||
{
|
{
|
||||||
printf("Portfwd - the init was not done !\n");
|
printf( "Portfwd - the init was not done!\n" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sprintf(port_str, "%d", port);
|
|
||||||
sprintf(port_str_internal, "%d", internal_port);
|
|
||||||
|
|
||||||
r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
|
sprintf( port_str, "%d", port );
|
||||||
port_str, port_str_internal, m_lanip.c_str(), "tomahawk", "TCP", NULL);
|
sprintf( port_str_internal, "%d", internal_port );
|
||||||
if(r!=0)
|
|
||||||
{
|
r = UPNP_AddPortMapping( m_urls->controlURL, m_data->first.servicetype, port_str, port_str_internal, m_lanip.c_str(), "tomahawk", "TCP", NULL, NULL );
|
||||||
printf("AddPortMapping(%s, %s, %s) failed, code %d\n", port_str, port_str, m_lanip.c_str(), r);
|
if ( r != 0 )
|
||||||
return false;
|
{
|
||||||
}
|
printf( "AddPortMapping(%s, %s, %s) failed, code %d\n", port_str, port_str, m_lanip.c_str(), r );
|
||||||
return true;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Portfwd::remove( unsigned short port )
|
Portfwd::remove( unsigned short port )
|
||||||
{
|
{
|
||||||
char port_str[16];
|
char port_str[16];
|
||||||
printf("Portfwd::remove(%d)\n", port);
|
printf( "Portfwd::remove(%d)\n", port );
|
||||||
if(urls->controlURL[0] == '\0')
|
if ( m_urls->controlURL[0] == '\0' )
|
||||||
{
|
{
|
||||||
printf("Portfwd - the init was not done !\n");
|
printf( "Portfwd - the init was not done!\n" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sprintf(port_str, "%d", port);
|
|
||||||
int r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, port_str, "TCP", NULL);
|
sprintf( port_str, "%d", port );
|
||||||
|
int r = UPNP_DeletePortMapping( m_urls->controlURL, m_data->first.servicetype, port_str, "TCP", NULL );
|
||||||
return r == 0;
|
return r == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Portfwd::addBlockedDevice( const std::string& ip )
|
||||||
|
{
|
||||||
|
printf( "adding blocked: %s\n", ip.c_str() );
|
||||||
|
m_blockedips.push_back( ip );
|
||||||
|
}
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
$Id: Changelog.txt,v 1.21 2010/02/02 18:24:43 nanard Exp $
|
|
||||||
|
|
||||||
2010/02/02:
|
|
||||||
Fixed compilation under Mac OS X
|
|
||||||
|
|
||||||
2009/12/19:
|
|
||||||
improve and fix building under Windows.
|
|
||||||
Project files for MS Visual Studio 2008
|
|
||||||
More simple (and working) code for Win32.
|
|
||||||
More checks in the /proc/net/route parsing. Add some comments.
|
|
||||||
|
|
||||||
2009/08/04:
|
|
||||||
improving getgateway.c for windows
|
|
||||||
|
|
||||||
2009/07/13:
|
|
||||||
Adding Haiku code in getgateway.c
|
|
||||||
|
|
||||||
2009/06/04:
|
|
||||||
Adding Python module thanks to David Wu
|
|
||||||
|
|
||||||
2009/03/10:
|
|
||||||
Trying to have windows get gateway working if not using DHCP
|
|
||||||
|
|
||||||
2009/02/27:
|
|
||||||
dont include declspec.h if not under WIN32.
|
|
||||||
|
|
||||||
2009/01/23:
|
|
||||||
Prefixed the libraries name with lib
|
|
||||||
|
|
||||||
2008/10/06:
|
|
||||||
Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE)
|
|
||||||
|
|
||||||
2008/07/03:
|
|
||||||
Adding WIN32 code from Robbie Hanson
|
|
||||||
|
|
||||||
2008/06/30:
|
|
||||||
added a Solaris implementation for getgateway().
|
|
||||||
added a LICENCE file to the distribution
|
|
||||||
|
|
||||||
2008/05/29:
|
|
||||||
Anonymous unions are forbidden in ANSI C. That was causing problems with
|
|
||||||
non-GCC compilers.
|
|
||||||
|
|
||||||
2008/04/28:
|
|
||||||
introduced strnatpmperr()
|
|
||||||
improved natpmpc.c sample
|
|
||||||
make install now install the binary
|
|
||||||
|
|
||||||
2007/12/13:
|
|
||||||
Fixed getgateway.c for working under OS X ;)
|
|
||||||
Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP
|
|
||||||
|
|
||||||
2007/12/11:
|
|
||||||
Fixed getgateway.c for compilation under Mac OS X
|
|
||||||
|
|
||||||
2007/12/01:
|
|
||||||
added some comments in .h
|
|
||||||
|
|
||||||
2007/11/30:
|
|
||||||
implemented almost everything
|
|
||||||
|
|
@@ -1,26 +0,0 @@
|
|||||||
Copyright (c) 2007-2009, 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.
|
|
||||||
|
|
@@ -1,7 +0,0 @@
|
|||||||
libnatpmp (c) 2007-2009 Thomas Bernard
|
|
||||||
contact : miniupnp@free.fr
|
|
||||||
|
|
||||||
see http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
or http://miniupnp.tuxfamily.org/libnatpmp.html
|
|
||||||
for some documentation and code samples.
|
|
||||||
|
|
@@ -1,30 +0,0 @@
|
|||||||
@echo Compiling with MinGW
|
|
||||||
@SET LIBS=-lws2_32 -liphlpapi
|
|
||||||
|
|
||||||
@echo Compile getgateway
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR testgetgateway.c
|
|
||||||
gcc -o testgetgateway getgateway.o testgetgateway.o %LIBS%
|
|
||||||
del testgetgateway.o
|
|
||||||
|
|
||||||
@echo Compile natpmp-static:
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmp.c
|
|
||||||
gcc -c -Wall -Os -DWIN32 wingettimeofday.c
|
|
||||||
ar cr natpmp.a getgateway.o natpmp.o wingettimeofday.o
|
|
||||||
del getgateway.o natpmp.o
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmpc.c
|
|
||||||
gcc -o natpmpc-static natpmpc.o natpmp.a %LIBS%
|
|
||||||
upx --best natpmpc-static.exe
|
|
||||||
del natpmpc.o
|
|
||||||
|
|
||||||
@echo Create natpmp.dll:
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS getgateway.c
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmp.c
|
|
||||||
dllwrap -k --driver-name gcc --def natpmp.def --output-def natpmp.dll.def --implib natpmp.lib -o natpmp.dll getgateway.o natpmp.o wingettimeofday.o %LIBS%
|
|
||||||
|
|
||||||
@echo Compile natpmp-shared:
|
|
||||||
gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmpc.c
|
|
||||||
gcc -o natpmpc-shared natpmpc.o natpmp.lib -lws2_32
|
|
||||||
upx --best natpmpc-shared.exe
|
|
||||||
del *.o
|
|
@@ -1,15 +0,0 @@
|
|||||||
#ifndef __DECLSPEC_H__
|
|
||||||
#define __DECLSPEC_H__
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(STATICLIB)
|
|
||||||
#ifdef NATPMP_EXPORTS
|
|
||||||
#define LIBSPEC __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define LIBSPEC __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define LIBSPEC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@@ -1,554 +0,0 @@
|
|||||||
/* $Id: getgateway.c,v 1.19 2009/12/19 15:20:45 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2009, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
/* There is no portable method to get the default route gateway.
|
|
||||||
* So below are four (or five ?) differents functions implementing this.
|
|
||||||
* Parsing /proc/net/route is for linux.
|
|
||||||
* sysctl is the way to access such informations on BSD systems.
|
|
||||||
* Many systems should provide route information through raw PF_ROUTE
|
|
||||||
* sockets.
|
|
||||||
* In MS Windows, default gateway is found by looking into the registry
|
|
||||||
* or by using GetBestRoute(). */
|
|
||||||
#ifdef __linux__
|
|
||||||
#define USE_PROC_NET_ROUTE
|
|
||||||
#undef USE_SOCKET_ROUTE
|
|
||||||
#undef USE_SYSCTL_NET_ROUTE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BSD
|
|
||||||
#undef USE_PROC_NET_ROUTE
|
|
||||||
#define USE_SOCKET_ROUTE
|
|
||||||
#undef USE_SYSCTL_NET_ROUTE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#undef USE_PROC_NET_ROUTE
|
|
||||||
#undef USE_SOCKET_ROUTE
|
|
||||||
#define USE_SYSCTL_NET_ROUTE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined(sun) && defined(__SVR4))
|
|
||||||
#undef USE_PROC_NET_ROUTE
|
|
||||||
#define USE_SOCKET_ROUTE
|
|
||||||
#undef USE_SYSCTL_NET_ROUTE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#undef USE_PROC_NET_ROUTE
|
|
||||||
#undef USE_SOCKET_ROUTE
|
|
||||||
#undef USE_SYSCTL_NET_ROUTE
|
|
||||||
//#define USE_WIN32_CODE
|
|
||||||
#define USE_WIN32_CODE_2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
#undef USE_PROC_NET_ROUTE
|
|
||||||
#undef USE_SOCKET_ROUTE
|
|
||||||
#undef USE_SYSCTL_NET_ROUTE
|
|
||||||
#define USE_WIN32_CODE
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <w32api/windef.h>
|
|
||||||
#include <w32api/winbase.h>
|
|
||||||
#include <w32api/winreg.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __HAIKU__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#define USE_HAIKU_CODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SYSCTL_NET_ROUTE
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SOCKET_ROUTE
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_WIN32_CODE
|
|
||||||
#include <unknwn.h>
|
|
||||||
#include <winreg.h>
|
|
||||||
#define MAX_KEY_LENGTH 255
|
|
||||||
#define MAX_VALUE_LENGTH 16383
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_WIN32_CODE_2
|
|
||||||
#include <windows.h>
|
|
||||||
#include <iphlpapi.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "getgateway.h"
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
#define SUCCESS (0)
|
|
||||||
#define FAILED (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_PROC_NET_ROUTE
|
|
||||||
/*
|
|
||||||
parse /proc/net/route which is as follow :
|
|
||||||
|
|
||||||
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
wlan0 0001A8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
eth0 0000FEA9 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
wlan0 00000000 0101A8C0 0003 0 0 0 00000000 0 0 0
|
|
||||||
eth0 00000000 00000000 0001 0 0 1000 00000000 0 0 0
|
|
||||||
|
|
||||||
One header line, and then one line by route by route table entry.
|
|
||||||
*/
|
|
||||||
int getdefaultgateway(in_addr_t * addr)
|
|
||||||
{
|
|
||||||
unsigned long d, g;
|
|
||||||
char buf[256];
|
|
||||||
int line = 0;
|
|
||||||
FILE * f;
|
|
||||||
char * p;
|
|
||||||
f = fopen("/proc/net/route", "r");
|
|
||||||
if(!f)
|
|
||||||
return FAILED;
|
|
||||||
while(fgets(buf, sizeof(buf), f)) {
|
|
||||||
if(line > 0) { /* skip the first line */
|
|
||||||
p = buf;
|
|
||||||
/* skip the interface name */
|
|
||||||
while(*p && !isspace(*p))
|
|
||||||
p++;
|
|
||||||
while(*p && isspace(*p))
|
|
||||||
p++;
|
|
||||||
if(sscanf(p, "%lx%lx", &d, &g)==2) {
|
|
||||||
if(d == 0 && g != 0) { /* default */
|
|
||||||
*addr = g;
|
|
||||||
fclose(f);
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
/* default route not found ! */
|
|
||||||
if(f)
|
|
||||||
fclose(f);
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
#endif /* #ifdef USE_PROC_NET_ROUTE */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SYSCTL_NET_ROUTE
|
|
||||||
|
|
||||||
#define ROUNDUP(a) \
|
|
||||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
|
||||||
|
|
||||||
int getdefaultgateway(in_addr_t * addr)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
/* net.route.0.inet.dump.0.0 ? */
|
|
||||||
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
|
|
||||||
NET_RT_DUMP, 0, 0/*tableid*/};
|
|
||||||
#endif
|
|
||||||
/* net.route.0.inet.flags.gateway */
|
|
||||||
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
|
|
||||||
NET_RT_FLAGS, RTF_GATEWAY};
|
|
||||||
size_t l;
|
|
||||||
char * buf, * p;
|
|
||||||
struct rt_msghdr * rt;
|
|
||||||
struct sockaddr * sa;
|
|
||||||
struct sockaddr * sa_tab[RTAX_MAX];
|
|
||||||
int i;
|
|
||||||
int r = FAILED;
|
|
||||||
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if(l>0) {
|
|
||||||
buf = malloc(l);
|
|
||||||
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
|
|
||||||
free(buf);
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
|
|
||||||
rt = (struct rt_msghdr *)p;
|
|
||||||
sa = (struct sockaddr *)(rt + 1);
|
|
||||||
for(i=0; i<RTAX_MAX; i++) {
|
|
||||||
if(rt->rtm_addrs & (1 << i)) {
|
|
||||||
sa_tab[i] = sa;
|
|
||||||
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
|
|
||||||
} else {
|
|
||||||
sa_tab[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
|
|
||||||
&& sa_tab[RTAX_DST]->sa_family == AF_INET
|
|
||||||
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
|
|
||||||
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
|
|
||||||
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
|
|
||||||
r = SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#endif /* #ifdef USE_SYSCTL_NET_ROUTE */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SOCKET_ROUTE
|
|
||||||
/* Thanks to Darren Kenny for this code */
|
|
||||||
#define NEXTADDR(w, u) \
|
|
||||||
if (rtm_addrs & (w)) {\
|
|
||||||
l = sizeof(struct sockaddr); memmove(cp, &(u), l); cp += l;\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define rtm m_rtmsg.m_rtm
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct rt_msghdr m_rtm;
|
|
||||||
char m_space[512];
|
|
||||||
} m_rtmsg;
|
|
||||||
|
|
||||||
int getdefaultgateway(in_addr_t *addr)
|
|
||||||
{
|
|
||||||
int s, seq, l, rtm_addrs, i;
|
|
||||||
pid_t pid;
|
|
||||||
struct sockaddr so_dst, so_mask;
|
|
||||||
char *cp = m_rtmsg.m_space;
|
|
||||||
struct sockaddr *gate = NULL, *sa;
|
|
||||||
struct rt_msghdr *msg_hdr;
|
|
||||||
|
|
||||||
pid = getpid();
|
|
||||||
seq = 0;
|
|
||||||
rtm_addrs = RTA_DST | RTA_NETMASK;
|
|
||||||
|
|
||||||
memset(&so_dst, 0, sizeof(so_dst));
|
|
||||||
memset(&so_mask, 0, sizeof(so_mask));
|
|
||||||
memset(&rtm, 0, sizeof(struct rt_msghdr));
|
|
||||||
|
|
||||||
rtm.rtm_type = RTM_GET;
|
|
||||||
rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
|
|
||||||
rtm.rtm_version = RTM_VERSION;
|
|
||||||
rtm.rtm_seq = ++seq;
|
|
||||||
rtm.rtm_addrs = rtm_addrs;
|
|
||||||
|
|
||||||
so_dst.sa_family = AF_INET;
|
|
||||||
so_mask.sa_family = AF_INET;
|
|
||||||
|
|
||||||
NEXTADDR(RTA_DST, so_dst);
|
|
||||||
NEXTADDR(RTA_NETMASK, so_mask);
|
|
||||||
|
|
||||||
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
|
|
||||||
|
|
||||||
s = socket(PF_ROUTE, SOCK_RAW, 0);
|
|
||||||
|
|
||||||
if (write(s, (char *)&m_rtmsg, l) < 0) {
|
|
||||||
close(s);
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
|
|
||||||
} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
|
|
||||||
|
|
||||||
close(s);
|
|
||||||
|
|
||||||
msg_hdr = &rtm;
|
|
||||||
|
|
||||||
cp = ((char *)(msg_hdr + 1));
|
|
||||||
if (msg_hdr->rtm_addrs) {
|
|
||||||
for (i = 1; i; i <<= 1)
|
|
||||||
if (i & msg_hdr->rtm_addrs) {
|
|
||||||
sa = (struct sockaddr *)cp;
|
|
||||||
if (i == RTA_GATEWAY )
|
|
||||||
gate = sa;
|
|
||||||
|
|
||||||
cp += sizeof(struct sockaddr);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (gate != NULL ) {
|
|
||||||
*addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr;
|
|
||||||
return SUCCESS;
|
|
||||||
} else {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* #ifdef USE_SOCKET_ROUTE */
|
|
||||||
|
|
||||||
#ifdef USE_WIN32_CODE
|
|
||||||
LIBSPEC int getdefaultgateway(in_addr_t * addr)
|
|
||||||
{
|
|
||||||
HKEY networkCardsKey;
|
|
||||||
HKEY networkCardKey;
|
|
||||||
HKEY interfacesKey;
|
|
||||||
HKEY interfaceKey;
|
|
||||||
DWORD i = 0;
|
|
||||||
DWORD numSubKeys = 0;
|
|
||||||
TCHAR keyName[MAX_KEY_LENGTH];
|
|
||||||
DWORD keyNameLength = MAX_KEY_LENGTH;
|
|
||||||
TCHAR keyValue[MAX_VALUE_LENGTH];
|
|
||||||
DWORD keyValueLength = MAX_VALUE_LENGTH;
|
|
||||||
DWORD keyValueType = REG_SZ;
|
|
||||||
TCHAR gatewayValue[MAX_VALUE_LENGTH];
|
|
||||||
DWORD gatewayValueLength = MAX_VALUE_LENGTH;
|
|
||||||
DWORD gatewayValueType = REG_MULTI_SZ;
|
|
||||||
int done = 0;
|
|
||||||
|
|
||||||
//const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
|
|
||||||
//const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
|
|
||||||
#ifdef UNICODE
|
|
||||||
LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
|
|
||||||
LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
|
|
||||||
#define STR_SERVICENAME L"ServiceName"
|
|
||||||
#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway"
|
|
||||||
#define STR_DEFAULTGATEWAY L"DefaultGateway"
|
|
||||||
#else
|
|
||||||
LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
|
|
||||||
LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
|
|
||||||
#define STR_SERVICENAME "ServiceName"
|
|
||||||
#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway"
|
|
||||||
#define STR_DEFAULTGATEWAY "DefaultGateway"
|
|
||||||
#endif
|
|
||||||
// The windows registry lists its primary network devices in the following location:
|
|
||||||
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
|
|
||||||
//
|
|
||||||
// Each network device has its own subfolder, named with an index, with various properties:
|
|
||||||
// -NetworkCards
|
|
||||||
// -5
|
|
||||||
// -Description = Broadcom 802.11n Network Adapter
|
|
||||||
// -ServiceName = {E35A72F8-5065-4097-8DFE-C7790774EE4D}
|
|
||||||
// -8
|
|
||||||
// -Description = Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller
|
|
||||||
// -ServiceName = {86226414-5545-4335-A9D1-5BD7120119AD}
|
|
||||||
//
|
|
||||||
// The above service name is the name of a subfolder within:
|
|
||||||
// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
|
|
||||||
//
|
|
||||||
// There may be more subfolders in this interfaces path than listed in the network cards path above:
|
|
||||||
// -Interfaces
|
|
||||||
// -{3a539854-6a70-11db-887c-806e6f6e6963}
|
|
||||||
// -DhcpIPAddress = 0.0.0.0
|
|
||||||
// -[more]
|
|
||||||
// -{E35A72F8-5065-4097-8DFE-C7790774EE4D}
|
|
||||||
// -DhcpIPAddress = 10.0.1.4
|
|
||||||
// -DhcpDefaultGateway = 10.0.1.1
|
|
||||||
// -[more]
|
|
||||||
// -{86226414-5545-4335-A9D1-5BD7120119AD}
|
|
||||||
// -DhcpIpAddress = 10.0.1.5
|
|
||||||
// -DhcpDefaultGateay = 10.0.1.1
|
|
||||||
// -[more]
|
|
||||||
//
|
|
||||||
// In order to extract this information, we enumerate each network card, and extract the ServiceName value.
|
|
||||||
// This is then used to open the interface subfolder, and attempt to extract a DhcpDefaultGateway value.
|
|
||||||
// Once one is found, we're done.
|
|
||||||
//
|
|
||||||
// It may be possible to simply enumerate the interface folders until we find one with a DhcpDefaultGateway value.
|
|
||||||
// However, the technique used is the technique most cited on the web, and we assume it to be more correct.
|
|
||||||
|
|
||||||
if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predifined key
|
|
||||||
networkCardsPath, // Name of registry subkey to open
|
|
||||||
0, // Reserved - must be zero
|
|
||||||
KEY_READ, // Mask - desired access rights
|
|
||||||
&networkCardsKey)) // Pointer to output key
|
|
||||||
{
|
|
||||||
// Unable to open network cards keys
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predefined key
|
|
||||||
interfacesPath, // Name of registry subkey to open
|
|
||||||
0, // Reserved - must be zero
|
|
||||||
KEY_READ, // Mask - desired access rights
|
|
||||||
&interfacesKey)) // Pointer to output key
|
|
||||||
{
|
|
||||||
// Unable to open interfaces key
|
|
||||||
RegCloseKey(networkCardsKey);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out how many subfolders are within the NetworkCards folder
|
|
||||||
RegQueryInfoKey(networkCardsKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
//printf( "Number of subkeys: %u\n", (unsigned int)numSubKeys);
|
|
||||||
|
|
||||||
// Enumrate through each subfolder within the NetworkCards folder
|
|
||||||
for(i = 0; i < numSubKeys && !done; i++)
|
|
||||||
{
|
|
||||||
keyNameLength = MAX_KEY_LENGTH;
|
|
||||||
if(ERROR_SUCCESS == RegEnumKeyEx(networkCardsKey, // Open registry key
|
|
||||||
i, // Index of subkey to retrieve
|
|
||||||
keyName, // Buffer that receives the name of the subkey
|
|
||||||
&keyNameLength, // Variable that receives the size of the above buffer
|
|
||||||
NULL, // Reserved - must be NULL
|
|
||||||
NULL, // Buffer that receives the class string
|
|
||||||
NULL, // Variable that receives the size of the above buffer
|
|
||||||
NULL)) // Variable that receives the last write time of subkey
|
|
||||||
{
|
|
||||||
if(RegOpenKeyEx(networkCardsKey, keyName, 0, KEY_READ, &networkCardKey) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
keyValueLength = MAX_VALUE_LENGTH;
|
|
||||||
if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey, // Open registry key
|
|
||||||
STR_SERVICENAME, // Name of key to query
|
|
||||||
NULL, // Reserved - must be NULL
|
|
||||||
&keyValueType, // Receives value type
|
|
||||||
(LPBYTE)keyValue, // Receives value
|
|
||||||
&keyValueLength)) // Receives value length in bytes
|
|
||||||
{
|
|
||||||
// printf("keyValue: %s\n", keyValue);
|
|
||||||
if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
gatewayValueLength = MAX_VALUE_LENGTH;
|
|
||||||
if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key
|
|
||||||
STR_DHCPDEFAULTGATEWAY, // Name of key to query
|
|
||||||
NULL, // Reserved - must be NULL
|
|
||||||
&gatewayValueType, // Receives value type
|
|
||||||
(LPBYTE)gatewayValue, // Receives value
|
|
||||||
&gatewayValueLength)) // Receives value length in bytes
|
|
||||||
{
|
|
||||||
// Check to make sure it's a string
|
|
||||||
if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
|
|
||||||
{
|
|
||||||
//printf("gatewayValue: %s\n", gatewayValue);
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key
|
|
||||||
STR_DEFAULTGATEWAY, // Name of key to query
|
|
||||||
NULL, // Reserved - must be NULL
|
|
||||||
&gatewayValueType, // Receives value type
|
|
||||||
(LPBYTE)gatewayValue,// Receives value
|
|
||||||
&gatewayValueLength)) // Receives value length in bytes
|
|
||||||
{
|
|
||||||
// Check to make sure it's a string
|
|
||||||
if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
|
|
||||||
{
|
|
||||||
//printf("gatewayValue: %s\n", gatewayValue);
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegCloseKey(interfaceKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegCloseKey(networkCardKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(interfacesKey);
|
|
||||||
RegCloseKey(networkCardsKey);
|
|
||||||
|
|
||||||
if(done)
|
|
||||||
{
|
|
||||||
#if UNICODE
|
|
||||||
char tmp[32];
|
|
||||||
for(i = 0; i < 32; i++) {
|
|
||||||
tmp[i] = (char)gatewayValue[i];
|
|
||||||
if(!tmp[i])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp[31] = '\0';
|
|
||||||
*addr = inet_addr(tmp);
|
|
||||||
#else
|
|
||||||
*addr = inet_addr(gatewayValue);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* #ifdef USE_WIN32_CODE */
|
|
||||||
|
|
||||||
#ifdef USE_WIN32_CODE_2
|
|
||||||
int getdefaultgateway(in_addr_t *addr)
|
|
||||||
{
|
|
||||||
MIB_IPFORWARDROW ip_forward;
|
|
||||||
memset(&ip_forward, 0, sizeof(ip_forward));
|
|
||||||
if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR)
|
|
||||||
return -1;
|
|
||||||
*addr = ip_forward.dwForwardNextHop;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* #ifdef USE_WIN32_CODE_2 */
|
|
||||||
|
|
||||||
#ifdef USE_HAIKU_CODE
|
|
||||||
int getdefaultgateway(in_addr_t *addr)
|
|
||||||
{
|
|
||||||
int fd, ret = -1;
|
|
||||||
struct ifconf config;
|
|
||||||
void *buffer = NULL;
|
|
||||||
struct ifreq *interface;
|
|
||||||
|
|
||||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (config.ifc_value < 1) {
|
|
||||||
goto fail; /* No routes */
|
|
||||||
}
|
|
||||||
if ((buffer = malloc(config.ifc_value)) == NULL) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
config.ifc_len = config.ifc_value;
|
|
||||||
config.ifc_buf = buffer;
|
|
||||||
if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
for (interface = buffer;
|
|
||||||
(uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) {
|
|
||||||
struct route_entry route = interface->ifr_route;
|
|
||||||
int intfSize;
|
|
||||||
if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) {
|
|
||||||
*addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr;
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
intfSize = sizeof(route) + IF_NAMESIZE;
|
|
||||||
if (route.destination != NULL) {
|
|
||||||
intfSize += route.destination->sa_len;
|
|
||||||
}
|
|
||||||
if (route.mask != NULL) {
|
|
||||||
intfSize += route.mask->sa_len;
|
|
||||||
}
|
|
||||||
if (route.gateway != NULL) {
|
|
||||||
intfSize += route.gateway->sa_len;
|
|
||||||
}
|
|
||||||
interface = (struct ifreq *)((uint8_t *)interface + intfSize);
|
|
||||||
}
|
|
||||||
fail:
|
|
||||||
free(buffer);
|
|
||||||
close(fd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif /* #ifdef USE_HAIKU_CODE */
|
|
||||||
|
|
||||||
|
|
@@ -1,36 +0,0 @@
|
|||||||
/* $Id: getgateway.h,v 1.4 2009/12/19 12:00:00 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#ifndef __GETGATEWAY_H__
|
|
||||||
#define __GETGATEWAY_H__
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <stdint.h>
|
|
||||||
#else
|
|
||||||
typedef unsigned long uint32_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#endif
|
|
||||||
#define in_addr_t uint32_t
|
|
||||||
#endif
|
|
||||||
#include "declspec.h"
|
|
||||||
|
|
||||||
/* getdefaultgateway() :
|
|
||||||
* return value :
|
|
||||||
* 0 : success
|
|
||||||
* -1 : failure */
|
|
||||||
LIBSPEC int getdefaultgateway(in_addr_t * addr);
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,268 +0,0 @@
|
|||||||
/* $Id: libnatpmpmodule.c,v 1.3 2009/12/19 12:00:00 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
* http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#include <Python.h>
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STATICLIB
|
|
||||||
#include "structmember.h"
|
|
||||||
#include "natpmp.h"
|
|
||||||
|
|
||||||
/* for compatibility with Python < 2.4 */
|
|
||||||
#ifndef Py_RETURN_NONE
|
|
||||||
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_RETURN_TRUE
|
|
||||||
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_RETURN_FALSE
|
|
||||||
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
|
|
||||||
/* Type-specific fields go here. */
|
|
||||||
unsigned int discoverdelay;
|
|
||||||
|
|
||||||
natpmp_t natpmp;
|
|
||||||
} NATPMPObject;
|
|
||||||
|
|
||||||
static PyMemberDef NATPMP_members[] = {
|
|
||||||
{"discoverdelay", T_UINT, offsetof(NATPMPObject, discoverdelay),
|
|
||||||
0/*READWRITE*/, "value in ms used to wait for NATPMP responses"
|
|
||||||
},
|
|
||||||
{NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
NATPMPObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
||||||
{
|
|
||||||
NATPMPObject *self;
|
|
||||||
|
|
||||||
self = (NATPMPObject *)type->tp_alloc(type, 0);
|
|
||||||
if (self) {
|
|
||||||
initnatpmp(&self->natpmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (PyObject *)self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
NATPMPObject_dealloc(NATPMPObject *self)
|
|
||||||
{
|
|
||||||
closenatpmp(&self->natpmp);
|
|
||||||
self->ob_type->tp_free((PyObject*)self);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
NATPMP_externalipaddress(NATPMPObject *self)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct timeval timeout;
|
|
||||||
fd_set fds;
|
|
||||||
natpmpresp_t response;
|
|
||||||
|
|
||||||
r = sendpublicaddressrequest(&self->natpmp);
|
|
||||||
|
|
||||||
if (r < 0) {
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
PyErr_SetString(PyExc_Exception, strnatpmperr(r));
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(self->natpmp.s, &fds);
|
|
||||||
getnatpmprequesttimeout(&self->natpmp, &timeout);
|
|
||||||
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
|
|
||||||
r = readnatpmpresponseorretry(&self->natpmp, &response);
|
|
||||||
if (r < 0 && r != NATPMP_TRYAGAIN) {
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
PyErr_SetString(PyExc_Exception, strnatpmperr(r));
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} while (r == NATPMP_TRYAGAIN);
|
|
||||||
|
|
||||||
return Py_BuildValue("s", inet_ntoa(response.pnu.publicaddress.addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
NATPMP_domapping(natpmp_t *n, unsigned short eport, unsigned short iport,
|
|
||||||
const char *protocol, unsigned int lifetime)
|
|
||||||
{
|
|
||||||
int proto;
|
|
||||||
struct timeval timeout;
|
|
||||||
fd_set fds;
|
|
||||||
natpmpresp_t response;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!strncasecmp("tcp", protocol, 3)) {
|
|
||||||
proto = NATPMP_PROTOCOL_TCP;
|
|
||||||
} else if (!strncasecmp("udp", protocol, 3)) {
|
|
||||||
proto = NATPMP_PROTOCOL_UDP;
|
|
||||||
} else {
|
|
||||||
PyErr_SetString(PyExc_Exception, "Unknown protocol");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sendnewportmappingrequest(n, proto, iport, eport,
|
|
||||||
lifetime);
|
|
||||||
|
|
||||||
if (r < 0) {
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
PyErr_SetString(PyExc_Exception, strnatpmperr(r));
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(n->s, &fds);
|
|
||||||
getnatpmprequesttimeout(n, &timeout);
|
|
||||||
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
|
|
||||||
r = readnatpmpresponseorretry(n, &response);
|
|
||||||
if (r < 0 && r != NATPMP_TRYAGAIN) {
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
PyErr_SetString(PyExc_Exception, strnatpmperr(r));
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} while (r == NATPMP_TRYAGAIN);
|
|
||||||
|
|
||||||
return Py_BuildValue("H", response.pnu.newportmapping.mappedpublicport);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* AddPortMapping(externalPort, protocol, internalPort, lifetime)
|
|
||||||
* protocol is 'UDP' or 'TCP' */
|
|
||||||
static PyObject *
|
|
||||||
NATPMP_addportmapping(NATPMPObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
unsigned short eport;
|
|
||||||
unsigned short iport;
|
|
||||||
unsigned int lifetime;
|
|
||||||
const char *protocol;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport, &lifetime))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return NATPMP_domapping(&self->natpmp, eport, iport, protocol, lifetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DeletePortMapping(externalPort, protocol, internalPort)
|
|
||||||
* protocol is 'UDP' or 'TCP' */
|
|
||||||
static PyObject *
|
|
||||||
NATPMP_deleteportmapping(NATPMPObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
unsigned short eport;
|
|
||||||
unsigned short iport;
|
|
||||||
const char *protocol;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return NATPMP_domapping(&self->natpmp, eport, iport, protocol, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* natpmp.NATPMP object Method Table */
|
|
||||||
static PyMethodDef NATPMP_methods[] = {
|
|
||||||
{"externalipaddress", (PyCFunction)NATPMP_externalipaddress, METH_NOARGS,
|
|
||||||
"return external IP address"
|
|
||||||
},
|
|
||||||
{"addportmapping", (PyCFunction)NATPMP_addportmapping, METH_VARARGS,
|
|
||||||
"add a port mapping"
|
|
||||||
},
|
|
||||||
{"deleteportmapping", (PyCFunction)NATPMP_deleteportmapping, METH_VARARGS,
|
|
||||||
"delete a port mapping"
|
|
||||||
},
|
|
||||||
{NULL} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject NATPMPType = {
|
|
||||||
PyObject_HEAD_INIT(NULL)
|
|
||||||
0, /*ob_size*/
|
|
||||||
"libnatpmp.NATPMP", /*tp_name*/
|
|
||||||
sizeof(NATPMPObject), /*tp_basicsize*/
|
|
||||||
0, /*tp_itemsize*/
|
|
||||||
(destructor)NATPMPObject_dealloc, /*tp_dealloc*/
|
|
||||||
0, /*tp_print*/
|
|
||||||
0, /*tp_getattr*/
|
|
||||||
0, /*tp_setattr*/
|
|
||||||
0, /*tp_compare*/
|
|
||||||
0, /*tp_repr*/
|
|
||||||
0, /*tp_as_number*/
|
|
||||||
0, /*tp_as_sequence*/
|
|
||||||
0, /*tp_as_mapping*/
|
|
||||||
0, /*tp_hash */
|
|
||||||
0, /*tp_call*/
|
|
||||||
0, /*tp_str*/
|
|
||||||
0, /*tp_getattro*/
|
|
||||||
0, /*tp_setattro*/
|
|
||||||
0, /*tp_as_buffer*/
|
|
||||||
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
|
||||||
"NATPMP objects", /* tp_doc */
|
|
||||||
0, /* tp_traverse */
|
|
||||||
0, /* tp_clear */
|
|
||||||
0, /* tp_richcompare */
|
|
||||||
0, /* tp_weaklistoffset */
|
|
||||||
0, /* tp_iter */
|
|
||||||
0, /* tp_iternext */
|
|
||||||
NATPMP_methods, /* tp_methods */
|
|
||||||
NATPMP_members, /* tp_members */
|
|
||||||
0, /* tp_getset */
|
|
||||||
0, /* tp_base */
|
|
||||||
0, /* tp_dict */
|
|
||||||
0, /* tp_descr_get */
|
|
||||||
0, /* tp_descr_set */
|
|
||||||
0, /* tp_dictoffset */
|
|
||||||
0, /* tp_init */
|
|
||||||
0, /* tp_alloc */
|
|
||||||
NATPMPObject_new, /* tp_new */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* module methods */
|
|
||||||
static PyMethodDef libnatpmp_methods[] = {
|
|
||||||
{NULL} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
|
|
||||||
#define PyMODINIT_FUNC void
|
|
||||||
#endif
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
initlibnatpmp(void)
|
|
||||||
{
|
|
||||||
PyObject* m;
|
|
||||||
|
|
||||||
if (PyType_Ready(&NATPMPType) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m = Py_InitModule3("libnatpmp", libnatpmp_methods,
|
|
||||||
"libnatpmp module.");
|
|
||||||
|
|
||||||
Py_INCREF(&NATPMPType);
|
|
||||||
PyModule_AddObject(m, "NATPMP", (PyObject *)&NATPMPType);
|
|
||||||
}
|
|
||||||
|
|
@@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
|
||||||
# Visual C++ Express 2008
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnatpmp", "libnatpmp.vcproj", "{D59B6527-F3DE-4D26-A08D-52F1EE989301}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "natpmpc-static", "natpmpc-static.vcproj", "{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{D59B6527-F3DE-4D26-A08D-52F1EE989301} = {D59B6527-F3DE-4D26-A08D-52F1EE989301}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
@@ -1,195 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9,00"
|
|
||||||
Name="libnatpmp"
|
|
||||||
ProjectGUID="{D59B6527-F3DE-4D26-A08D-52F1EE989301}"
|
|
||||||
RootNamespace="libnatpmp"
|
|
||||||
Keyword="Win32Proj"
|
|
||||||
TargetFrameworkVersion="196613"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="4"
|
|
||||||
CharacterSet="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;STATICLIB"
|
|
||||||
MinimalRebuild="true"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="3"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLibrarianTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="4"
|
|
||||||
CharacterSet="1"
|
|
||||||
WholeProgramOptimization="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;STATICLIB"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLibrarianTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers sources"
|
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\getgateway.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natpmp.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\wingettimeofday.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers d'en-t<>te"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\declspec.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\getgateway.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natpmp.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\wingettimeofday.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers de ressources"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@@ -1,195 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9,00"
|
|
||||||
Name="natpmpc-static"
|
|
||||||
ProjectGUID="{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}"
|
|
||||||
RootNamespace="natpmpcstatic"
|
|
||||||
Keyword="Win32Proj"
|
|
||||||
TargetFrameworkVersion="196613"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;STATICLIB;_CRT_SECURE_NO_WARNINGS"
|
|
||||||
MinimalRebuild="true"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="3"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="ws2_32.lib Iphlpapi.lib"
|
|
||||||
LinkIncremental="2"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="1"
|
|
||||||
WholeProgramOptimization="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;STATICLIB;_CRT_SECURE_NO_WARNINGS"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="ws2_32.lib iphlpapi.lib"
|
|
||||||
LinkIncremental="1"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers sources"
|
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natpmpc.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers d'en-t<>te"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers de ressources"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@@ -1,346 +0,0 @@
|
|||||||
/* $Id: natpmp.c,v 1.12 2009/12/19 14:10:09 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2009, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
* http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#ifdef __linux__
|
|
||||||
#define _BSD_SOURCE 1
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <errno.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <io.h>
|
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
|
||||||
#define ECONNREFUSED WSAECONNREFUSED
|
|
||||||
#include "wingettimeofday.h"
|
|
||||||
#else
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#define closesocket close
|
|
||||||
#endif
|
|
||||||
#include "natpmp.h"
|
|
||||||
#include "getgateway.h"
|
|
||||||
|
|
||||||
LIBSPEC int initnatpmp(natpmp_t * p)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
u_long ioctlArg = 1;
|
|
||||||
#else
|
|
||||||
int flags;
|
|
||||||
#endif
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
if(!p)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
memset(p, 0, sizeof(natpmp_t));
|
|
||||||
p->s = socket(PF_INET, SOCK_DGRAM, 0);
|
|
||||||
if(p->s < 0)
|
|
||||||
return NATPMP_ERR_SOCKETERROR;
|
|
||||||
#ifdef WIN32
|
|
||||||
if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR)
|
|
||||||
return NATPMP_ERR_FCNTLERROR;
|
|
||||||
#else
|
|
||||||
if((flags = fcntl(p->s, F_GETFL, 0)) < 0)
|
|
||||||
return NATPMP_ERR_FCNTLERROR;
|
|
||||||
if(fcntl(p->s, F_SETFL, flags | O_NONBLOCK) < 0)
|
|
||||||
return NATPMP_ERR_FCNTLERROR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(getdefaultgateway(&(p->gateway)) < 0)
|
|
||||||
return NATPMP_ERR_CANNOTGETGATEWAY;
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(NATPMP_PORT);
|
|
||||||
addr.sin_addr.s_addr = p->gateway;
|
|
||||||
if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
|
||||||
return NATPMP_ERR_CONNECTERR;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int closenatpmp(natpmp_t * p)
|
|
||||||
{
|
|
||||||
if(!p)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
if(closesocket(p->s) < 0)
|
|
||||||
return NATPMP_ERR_CLOSEERR;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sendpendingrequest(natpmp_t * p)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
/* struct sockaddr_in addr;*/
|
|
||||||
if(!p)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
/* memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(NATPMP_PORT);
|
|
||||||
addr.sin_addr.s_addr = p->gateway;
|
|
||||||
r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0,
|
|
||||||
(struct sockaddr *)&addr, sizeof(addr));*/
|
|
||||||
r = (int)send(p->s, p->pending_request, p->pending_request_len, 0);
|
|
||||||
return (r<0) ? NATPMP_ERR_SENDERR : r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sendnatpmprequest(natpmp_t * p)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
if(!p)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
/* TODO : check if no request is allready pending */
|
|
||||||
p->has_pending_request = 1;
|
|
||||||
p->try_number = 1;
|
|
||||||
n = sendpendingrequest(p);
|
|
||||||
gettimeofday(&p->retry_time, NULL); // check errors !
|
|
||||||
p->retry_time.tv_usec += 250000; /* add 250ms */
|
|
||||||
if(p->retry_time.tv_usec >= 1000000) {
|
|
||||||
p->retry_time.tv_usec -= 1000000;
|
|
||||||
p->retry_time.tv_sec++;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
|
|
||||||
{
|
|
||||||
struct timeval now;
|
|
||||||
if(!p || !timeout)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
if(!p->has_pending_request)
|
|
||||||
return NATPMP_ERR_NOPENDINGREQ;
|
|
||||||
if(gettimeofday(&now, NULL) < 0)
|
|
||||||
return NATPMP_ERR_GETTIMEOFDAYERR;
|
|
||||||
timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec;
|
|
||||||
timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec;
|
|
||||||
if(timeout->tv_usec < 0) {
|
|
||||||
timeout->tv_usec += 1000000;
|
|
||||||
timeout->tv_sec--;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int sendpublicaddressrequest(natpmp_t * p)
|
|
||||||
{
|
|
||||||
if(!p)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
//static const unsigned char request[] = { 0, 0 };
|
|
||||||
p->pending_request[0] = 0;
|
|
||||||
p->pending_request[1] = 0;
|
|
||||||
p->pending_request_len = 2;
|
|
||||||
// TODO: return 0 instead of sizeof(request) ??
|
|
||||||
return sendnatpmprequest(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
|
|
||||||
uint16_t privateport, uint16_t publicport,
|
|
||||||
uint32_t lifetime)
|
|
||||||
{
|
|
||||||
if(!p || (protocol!=NATPMP_PROTOCOL_TCP && protocol!=NATPMP_PROTOCOL_UDP))
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
p->pending_request[0] = 0;
|
|
||||||
p->pending_request[1] = protocol;
|
|
||||||
p->pending_request[2] = 0;
|
|
||||||
p->pending_request[3] = 0;
|
|
||||||
*((uint16_t *)(p->pending_request + 4)) = htons(privateport);
|
|
||||||
*((uint16_t *)(p->pending_request + 6)) = htons(publicport);
|
|
||||||
*((uint32_t *)(p->pending_request + 8)) = htonl(lifetime);
|
|
||||||
p->pending_request_len = 12;
|
|
||||||
return sendnatpmprequest(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response)
|
|
||||||
{
|
|
||||||
unsigned char buf[16];
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
socklen_t addrlen = sizeof(addr);
|
|
||||||
int n;
|
|
||||||
if(!p)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
n = recvfrom(p->s, buf, sizeof(buf), 0,
|
|
||||||
(struct sockaddr *)&addr, &addrlen);
|
|
||||||
if(n<0)
|
|
||||||
switch(errno) {
|
|
||||||
/*case EAGAIN:*/
|
|
||||||
case EWOULDBLOCK:
|
|
||||||
n = NATPMP_TRYAGAIN;
|
|
||||||
break;
|
|
||||||
case ECONNREFUSED:
|
|
||||||
n = NATPMP_ERR_NOGATEWAYSUPPORT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
n = NATPMP_ERR_RECVFROM;
|
|
||||||
}
|
|
||||||
/* check that addr is correct (= gateway) */
|
|
||||||
else if(addr.sin_addr.s_addr != p->gateway)
|
|
||||||
n = NATPMP_ERR_WRONGPACKETSOURCE;
|
|
||||||
else {
|
|
||||||
response->resultcode = ntohs(*((uint16_t *)(buf + 2)));
|
|
||||||
response->epoch = ntohl(*((uint32_t *)(buf + 4)));
|
|
||||||
if(buf[0] != 0)
|
|
||||||
n = NATPMP_ERR_UNSUPPORTEDVERSION;
|
|
||||||
else if(buf[1] < 128 || buf[1] > 130)
|
|
||||||
n = NATPMP_ERR_UNSUPPORTEDOPCODE;
|
|
||||||
else if(response->resultcode != 0) {
|
|
||||||
switch(response->resultcode) {
|
|
||||||
case 1:
|
|
||||||
n = NATPMP_ERR_UNSUPPORTEDVERSION;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
n = NATPMP_ERR_NOTAUTHORIZED;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
n = NATPMP_ERR_NETWORKFAILURE;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
n = NATPMP_ERR_OUTOFRESOURCES;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
n = NATPMP_ERR_UNSUPPORTEDOPCODE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
n = NATPMP_ERR_UNDEFINEDERROR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
response->type = buf[1] & 0x7f;
|
|
||||||
if(buf[1] == 128)
|
|
||||||
//response->publicaddress.addr = *((uint32_t *)(buf + 8));
|
|
||||||
response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8));
|
|
||||||
else {
|
|
||||||
response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8)));
|
|
||||||
response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10)));
|
|
||||||
response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12)));
|
|
||||||
}
|
|
||||||
n = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
if(!p || !response)
|
|
||||||
return NATPMP_ERR_INVALIDARGS;
|
|
||||||
if(!p->has_pending_request)
|
|
||||||
return NATPMP_ERR_NOPENDINGREQ;
|
|
||||||
n = readnatpmpresponse(p, response);
|
|
||||||
if(n<0) {
|
|
||||||
if(n==NATPMP_TRYAGAIN) {
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL); // check errors !
|
|
||||||
if(timercmp(&now, &p->retry_time, >=)) {
|
|
||||||
int delay, r;
|
|
||||||
if(p->try_number >= 9) {
|
|
||||||
return NATPMP_ERR_NOGATEWAYSUPPORT;
|
|
||||||
}
|
|
||||||
/*printf("retry! %d\n", p->try_number);*/
|
|
||||||
delay = 250 * (1<<p->try_number); // ms
|
|
||||||
/*for(i=0; i<p->try_number; i++)
|
|
||||||
delay += delay;*/
|
|
||||||
p->retry_time.tv_sec += (delay / 1000);
|
|
||||||
p->retry_time.tv_usec += (delay % 1000) * 1000;
|
|
||||||
if(p->retry_time.tv_usec >= 1000000) {
|
|
||||||
p->retry_time.tv_usec -= 1000000;
|
|
||||||
p->retry_time.tv_sec++;
|
|
||||||
}
|
|
||||||
p->try_number++;
|
|
||||||
r = sendpendingrequest(p);
|
|
||||||
if(r<0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p->has_pending_request = 0;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
LIBSPEC const char * strnatpmperr(int r)
|
|
||||||
{
|
|
||||||
const char * s;
|
|
||||||
switch(r) {
|
|
||||||
case NATPMP_ERR_INVALIDARGS:
|
|
||||||
s = "invalid arguments";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_SOCKETERROR:
|
|
||||||
s = "socket() failed";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_CANNOTGETGATEWAY:
|
|
||||||
s = "cannot get default gateway ip address";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_CLOSEERR:
|
|
||||||
#ifdef WIN32
|
|
||||||
s = "closesocket() failed";
|
|
||||||
#else
|
|
||||||
s = "close() failed";
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_RECVFROM:
|
|
||||||
s = "recvfrom() failed";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_NOPENDINGREQ:
|
|
||||||
s = "no pending request";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_NOGATEWAYSUPPORT:
|
|
||||||
s = "the gateway does not support nat-pmp";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_CONNECTERR:
|
|
||||||
s = "connect() failed";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_WRONGPACKETSOURCE:
|
|
||||||
s = "packet not received from the default gateway";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_SENDERR:
|
|
||||||
s = "send() failed";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_FCNTLERROR:
|
|
||||||
s = "fcntl() failed";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_GETTIMEOFDAYERR:
|
|
||||||
s = "gettimeofday() failed";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_UNSUPPORTEDVERSION:
|
|
||||||
s = "unsupported nat-pmp version error from server";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_UNSUPPORTEDOPCODE:
|
|
||||||
s = "unsupported nat-pmp opcode error from server";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_UNDEFINEDERROR:
|
|
||||||
s = "undefined nat-pmp server error";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_NOTAUTHORIZED:
|
|
||||||
s = "not authorized";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_NETWORKFAILURE:
|
|
||||||
s = "network failure";
|
|
||||||
break;
|
|
||||||
case NATPMP_ERR_OUTOFRESOURCES:
|
|
||||||
s = "nat-pmp server out of resources";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s = "Unknown libnatpmp error";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
LIBRARY
|
|
||||||
; libnatpmp library
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
initnatpmp
|
|
||||||
closenatpmp
|
|
||||||
sendpublicaddressrequest
|
|
||||||
sendnewportmappingrequest
|
|
||||||
getnatpmprequesttimeout
|
|
||||||
readnatpmpresponseorretry
|
|
||||||
strnatpmperr
|
|
@@ -1,194 +0,0 @@
|
|||||||
/* $Id: natpmp.h,v 1.12 2009/12/19 12:00:00 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
* http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#ifndef __NATPMP_H__
|
|
||||||
#define __NATPMP_H__
|
|
||||||
|
|
||||||
/* NAT-PMP Port as defined by the NAT-PMP draft */
|
|
||||||
#define NATPMP_PORT (5351)
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <stdint.h>
|
|
||||||
#else
|
|
||||||
typedef unsigned long uint32_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#endif
|
|
||||||
#define in_addr_t uint32_t
|
|
||||||
#include "declspec.h"
|
|
||||||
#else
|
|
||||||
#define LIBSPEC
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int s; /* socket */
|
|
||||||
in_addr_t gateway; /* default gateway (IPv4) */
|
|
||||||
int has_pending_request;
|
|
||||||
unsigned char pending_request[12];
|
|
||||||
int pending_request_len;
|
|
||||||
int try_number;
|
|
||||||
struct timeval retry_time;
|
|
||||||
} natpmp_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t type; /* NATPMP_RESPTYPE_* */
|
|
||||||
uint16_t resultcode; /* NAT-PMP response code */
|
|
||||||
uint32_t epoch; /* Seconds since start of epoch */
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
//in_addr_t addr;
|
|
||||||
struct in_addr addr;
|
|
||||||
} publicaddress;
|
|
||||||
struct {
|
|
||||||
uint16_t privateport;
|
|
||||||
uint16_t mappedpublicport;
|
|
||||||
uint32_t lifetime;
|
|
||||||
} newportmapping;
|
|
||||||
} pnu;
|
|
||||||
} natpmpresp_t;
|
|
||||||
|
|
||||||
/* possible values for type field of natpmpresp_t */
|
|
||||||
#define NATPMP_RESPTYPE_PUBLICADDRESS (0)
|
|
||||||
#define NATPMP_RESPTYPE_UDPPORTMAPPING (1)
|
|
||||||
#define NATPMP_RESPTYPE_TCPPORTMAPPING (2)
|
|
||||||
|
|
||||||
/* Values to pass to sendnewportmappingrequest() */
|
|
||||||
#define NATPMP_PROTOCOL_UDP (1)
|
|
||||||
#define NATPMP_PROTOCOL_TCP (2)
|
|
||||||
|
|
||||||
/* return values */
|
|
||||||
/* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */
|
|
||||||
#define NATPMP_ERR_INVALIDARGS (-1)
|
|
||||||
/* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_SOCKETERROR (-2)
|
|
||||||
/* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */
|
|
||||||
#define NATPMP_ERR_CANNOTGETGATEWAY (-3)
|
|
||||||
/* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_CLOSEERR (-4)
|
|
||||||
/* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_RECVFROM (-5)
|
|
||||||
/* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while
|
|
||||||
* no NAT-PMP request was pending */
|
|
||||||
#define NATPMP_ERR_NOPENDINGREQ (-6)
|
|
||||||
/* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */
|
|
||||||
#define NATPMP_ERR_NOGATEWAYSUPPORT (-7)
|
|
||||||
/* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_CONNECTERR (-8)
|
|
||||||
/* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */
|
|
||||||
#define NATPMP_ERR_WRONGPACKETSOURCE (-9)
|
|
||||||
/* NATPMP_ERR_SENDERR : send() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_SENDERR (-10)
|
|
||||||
/* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_FCNTLERROR (-11)
|
|
||||||
/* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */
|
|
||||||
#define NATPMP_ERR_GETTIMEOFDAYERR (-12)
|
|
||||||
|
|
||||||
/* */
|
|
||||||
#define NATPMP_ERR_UNSUPPORTEDVERSION (-14)
|
|
||||||
#define NATPMP_ERR_UNSUPPORTEDOPCODE (-15)
|
|
||||||
|
|
||||||
/* Errors from the server : */
|
|
||||||
#define NATPMP_ERR_UNDEFINEDERROR (-49)
|
|
||||||
#define NATPMP_ERR_NOTAUTHORIZED (-51)
|
|
||||||
#define NATPMP_ERR_NETWORKFAILURE (-52)
|
|
||||||
#define NATPMP_ERR_OUTOFRESOURCES (-53)
|
|
||||||
|
|
||||||
/* NATPMP_TRYAGAIN : no data available for the moment. try again later */
|
|
||||||
#define NATPMP_TRYAGAIN (-100)
|
|
||||||
|
|
||||||
/* initnatpmp()
|
|
||||||
* initialize a natpmp_t object
|
|
||||||
* Return values :
|
|
||||||
* 0 = OK
|
|
||||||
* NATPMP_ERR_INVALIDARGS
|
|
||||||
* NATPMP_ERR_SOCKETERROR
|
|
||||||
* NATPMP_ERR_FCNTLERROR
|
|
||||||
* NATPMP_ERR_CANNOTGETGATEWAY
|
|
||||||
* NATPMP_ERR_CONNECTERR */
|
|
||||||
LIBSPEC int initnatpmp(natpmp_t * p);
|
|
||||||
|
|
||||||
/* closenatpmp()
|
|
||||||
* close resources associated with a natpmp_t object
|
|
||||||
* Return values :
|
|
||||||
* 0 = OK
|
|
||||||
* NATPMP_ERR_INVALIDARGS
|
|
||||||
* NATPMP_ERR_CLOSEERR */
|
|
||||||
LIBSPEC int closenatpmp(natpmp_t * p);
|
|
||||||
|
|
||||||
/* sendpublicaddressrequest()
|
|
||||||
* send a public address NAT-PMP request to the network gateway
|
|
||||||
* Return values :
|
|
||||||
* 2 = OK (size of the request)
|
|
||||||
* NATPMP_ERR_INVALIDARGS
|
|
||||||
* NATPMP_ERR_SENDERR */
|
|
||||||
LIBSPEC int sendpublicaddressrequest(natpmp_t * p);
|
|
||||||
|
|
||||||
/* sendnewportmappingrequest()
|
|
||||||
* send a new port mapping NAT-PMP request to the network gateway
|
|
||||||
* Arguments :
|
|
||||||
* protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP,
|
|
||||||
* lifetime is in seconds.
|
|
||||||
* To remove a port mapping, set lifetime to zero.
|
|
||||||
* To remove all port mappings to the host, set lifetime and both ports
|
|
||||||
* to zero.
|
|
||||||
* Return values :
|
|
||||||
* 12 = OK (size of the request)
|
|
||||||
* NATPMP_ERR_INVALIDARGS
|
|
||||||
* NATPMP_ERR_SENDERR */
|
|
||||||
LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
|
|
||||||
uint16_t privateport, uint16_t publicport,
|
|
||||||
uint32_t lifetime);
|
|
||||||
|
|
||||||
/* getnatpmprequesttimeout()
|
|
||||||
* fills the timeval structure with the timeout duration of the
|
|
||||||
* currently pending NAT-PMP request.
|
|
||||||
* Return values :
|
|
||||||
* 0 = OK
|
|
||||||
* NATPMP_ERR_INVALIDARGS
|
|
||||||
* NATPMP_ERR_GETTIMEOFDAYERR
|
|
||||||
* NATPMP_ERR_NOPENDINGREQ */
|
|
||||||
LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout);
|
|
||||||
|
|
||||||
/* readnatpmpresponseorretry()
|
|
||||||
* fills the natpmpresp_t structure if possible
|
|
||||||
* Return values :
|
|
||||||
* 0 = OK
|
|
||||||
* NATPMP_TRYAGAIN
|
|
||||||
* NATPMP_ERR_INVALIDARGS
|
|
||||||
* NATPMP_ERR_NOPENDINGREQ
|
|
||||||
* NATPMP_ERR_NOGATEWAYSUPPORT
|
|
||||||
* NATPMP_ERR_RECVFROM
|
|
||||||
* NATPMP_ERR_WRONGPACKETSOURCE
|
|
||||||
* NATPMP_ERR_UNSUPPORTEDVERSION
|
|
||||||
* NATPMP_ERR_UNSUPPORTEDOPCODE
|
|
||||||
* NATPMP_ERR_NOTAUTHORIZED
|
|
||||||
* NATPMP_ERR_NETWORKFAILURE
|
|
||||||
* NATPMP_ERR_OUTOFRESOURCES
|
|
||||||
* NATPMP_ERR_UNSUPPORTEDOPCODE
|
|
||||||
* NATPMP_ERR_UNDEFINEDERROR */
|
|
||||||
LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response);
|
|
||||||
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
LIBSPEC const char * strnatpmperr(int t);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,210 +0,0 @@
|
|||||||
/* $Id: natpmpc.c,v 1.7 2009/12/19 12:00:00 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
* http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#else
|
|
||||||
#define strcasecmp stricmp
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#include "natpmp.h"
|
|
||||||
|
|
||||||
void usage(FILE * out, const char * argv0)
|
|
||||||
{
|
|
||||||
fprintf(out, "Usage :\n");
|
|
||||||
fprintf(out, " %s\n", argv0);
|
|
||||||
fprintf(out, "\tdisplay the public IP address.\n");
|
|
||||||
fprintf(out, " %s -h\n", argv0);
|
|
||||||
fprintf(out, "\tdisplay this help screen.\n");
|
|
||||||
fprintf(out, " %s -a <public port> <private port> <protocol> [lifetime]\n", argv0);
|
|
||||||
fprintf(out, "\tadd a port mapping.\n");
|
|
||||||
fprintf(out, "\n In order to remove a mapping, set it with a lifetime of 0 seconds.\n");
|
|
||||||
fprintf(out, " To remove all mappings for your machine, use 0 as private port and lifetime.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sample code for using libnatpmp */
|
|
||||||
int main(int argc, char * * argv)
|
|
||||||
{
|
|
||||||
natpmp_t natpmp;
|
|
||||||
natpmpresp_t response;
|
|
||||||
int r;
|
|
||||||
int sav_errno;
|
|
||||||
struct timeval timeout;
|
|
||||||
fd_set fds;
|
|
||||||
int i;
|
|
||||||
int protocol = 0;
|
|
||||||
uint16_t privateport = 0;
|
|
||||||
uint16_t publicport = 0;
|
|
||||||
uint32_t lifetime = 3600;
|
|
||||||
int command = 0;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
WSADATA wsaData;
|
|
||||||
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
|
||||||
if(nResult != NO_ERROR)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WSAStartup() failed.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* argument parsing */
|
|
||||||
for(i=1; i<argc; i++) {
|
|
||||||
if(argv[i][0] == '-') {
|
|
||||||
switch(argv[i][1]) {
|
|
||||||
case 'h':
|
|
||||||
usage(stdout, argv[0]);
|
|
||||||
return 0;
|
|
||||||
case 'a':
|
|
||||||
command = 'a';
|
|
||||||
if(argc < i + 3) {
|
|
||||||
fprintf(stderr, "Not enough arguments for option -a\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
if(1 != sscanf(argv[i], "%hu", &publicport)) {
|
|
||||||
fprintf(stderr, "%s is not a correct 16bits unsigned integer\n", argv[i]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
if(1 != sscanf(argv[i], "%hu", &privateport)) {
|
|
||||||
fprintf(stderr, "%s is not a correct 16bits unsigned integer\n", argv[i]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
if(0 == strcasecmp(argv[i], "tcp"))
|
|
||||||
protocol = NATPMP_PROTOCOL_TCP;
|
|
||||||
else if(0 == strcasecmp(argv[i], "udp"))
|
|
||||||
protocol = NATPMP_PROTOCOL_UDP;
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "%s is not a valid protocol\n", argv[i]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(argc >= i) {
|
|
||||||
i++;
|
|
||||||
if(1 != sscanf(argv[i], "%u", &lifetime)) {
|
|
||||||
fprintf(stderr, "%s is not a correct 32bits unsigned integer\n", argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unknown option %s\n", argv[i]);
|
|
||||||
usage(stderr, argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Unknown option %s\n", argv[i]);
|
|
||||||
usage(stderr, argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initnatpmp() */
|
|
||||||
r = initnatpmp(&natpmp);
|
|
||||||
printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS");
|
|
||||||
if(r<0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* sendpublicaddressrequest() */
|
|
||||||
r = sendpublicaddressrequest(&natpmp);
|
|
||||||
printf("sendpublicaddressrequest returned %d (%s)\n",
|
|
||||||
r, r==2?"SUCCESS":"FAILED");
|
|
||||||
if(r<0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(natpmp.s, &fds);
|
|
||||||
getnatpmprequesttimeout(&natpmp, &timeout);
|
|
||||||
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
|
|
||||||
r = readnatpmpresponseorretry(&natpmp, &response);
|
|
||||||
sav_errno = errno;
|
|
||||||
printf("readnatpmpresponseorretry returned %d (%s)\n",
|
|
||||||
r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
|
|
||||||
if(r<0 && r!=NATPMP_TRYAGAIN) {
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n",
|
|
||||||
strnatpmperr(r));
|
|
||||||
#endif
|
|
||||||
fprintf(stderr, " errno=%d '%s'\n",
|
|
||||||
sav_errno, strerror(sav_errno));
|
|
||||||
}
|
|
||||||
} while(r==NATPMP_TRYAGAIN);
|
|
||||||
if(r<0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* TODO : check that response.type == 0 */
|
|
||||||
printf("Public IP address : %s\n", inet_ntoa(response.pnu.publicaddress.addr));
|
|
||||||
printf("epoch = %u\n", response.epoch);
|
|
||||||
|
|
||||||
if(command == 'a') {
|
|
||||||
/* sendnewportmappingrequest() */
|
|
||||||
r = sendnewportmappingrequest(&natpmp, protocol,
|
|
||||||
privateport, publicport,
|
|
||||||
lifetime);
|
|
||||||
printf("sendnewportmappingrequest returned %d (%s)\n",
|
|
||||||
r, r==12?"SUCCESS":"FAILED");
|
|
||||||
if(r < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(natpmp.s, &fds);
|
|
||||||
getnatpmprequesttimeout(&natpmp, &timeout);
|
|
||||||
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
|
|
||||||
r = readnatpmpresponseorretry(&natpmp, &response);
|
|
||||||
printf("readnatpmpresponseorretry returned %d (%s)\n",
|
|
||||||
r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
|
|
||||||
} while(r==NATPMP_TRYAGAIN);
|
|
||||||
if(r<0) {
|
|
||||||
#ifdef ENABLE_STRNATPMPERR
|
|
||||||
fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n",
|
|
||||||
strnatpmperr(r));
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Mapped public port %hu protocol %s to local port %hu "
|
|
||||||
"liftime %u\n",
|
|
||||||
response.pnu.newportmapping.mappedpublicport,
|
|
||||||
response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
|
|
||||||
(response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" :
|
|
||||||
"UNKNOWN"),
|
|
||||||
response.pnu.newportmapping.privateport,
|
|
||||||
response.pnu.newportmapping.lifetime);
|
|
||||||
printf("epoch = %u\n", response.epoch);
|
|
||||||
}
|
|
||||||
|
|
||||||
r = closenatpmp(&natpmp);
|
|
||||||
printf("closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED");
|
|
||||||
if(r<0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,15 +0,0 @@
|
|||||||
#! /usr/bin/python
|
|
||||||
# $Id: setup.py,v 1.2 2009/06/04 21:37:06 nanard Exp $
|
|
||||||
#
|
|
||||||
# python script to build the libnatpmp module under unix
|
|
||||||
#
|
|
||||||
# replace libnatpmp.a by libnatpmp.so for shared library usage
|
|
||||||
from distutils.core import setup, Extension
|
|
||||||
setup(name="libnatpmp", version="1.0",
|
|
||||||
ext_modules=[
|
|
||||||
Extension(name="libnatpmp", sources=["libnatpmpmodule.c"],
|
|
||||||
extra_objects=["libnatpmp.a"],
|
|
||||||
define_macros=[('ENABLE_STRNATPMPERR', None)]
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
|
|
@@ -1,14 +0,0 @@
|
|||||||
#! /usr/bin/python
|
|
||||||
# $Id: setupmingw32.py,v 1.2 2009/06/04 21:37:06 nanard Exp $
|
|
||||||
# python script to build the miniupnpc module under windows
|
|
||||||
#
|
|
||||||
from distutils.core import setup, Extension
|
|
||||||
setup(name="libnatpmp", version="1.0",
|
|
||||||
ext_modules=[
|
|
||||||
Extension(name="libnatpmp", sources=["libnatpmpmodule.c"],
|
|
||||||
libraries=["ws2_32"],
|
|
||||||
extra_objects=["libnatpmp.a"],
|
|
||||||
define_macros=[('ENABLE_STRNATPMPERR', None)]
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
|
|
@@ -1,42 +0,0 @@
|
|||||||
/* $Id: testgetgateway.c,v 1.4 2008/07/02 22:33:06 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#include <stdio.h>
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#include "getgateway.h"
|
|
||||||
|
|
||||||
int main(int argc, char * * argv)
|
|
||||||
{
|
|
||||||
struct in_addr gatewayaddr;
|
|
||||||
int r;
|
|
||||||
#ifdef WIN32
|
|
||||||
uint32_t temp = 0;
|
|
||||||
r = getdefaultgateway(&temp);
|
|
||||||
gatewayaddr.S_un.S_addr = temp;
|
|
||||||
#else
|
|
||||||
r = getdefaultgateway(&(gatewayaddr.s_addr));
|
|
||||||
#endif
|
|
||||||
if(r>=0)
|
|
||||||
printf("default gateway : %s\n", inet_ntoa(gatewayaddr));
|
|
||||||
else
|
|
||||||
fprintf(stderr, "getdefaultgateway() failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,50 +0,0 @@
|
|||||||
/* $Id: wingettimeofday.c,v 1.3 2009/12/19 12:00:00 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
* http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#ifdef WIN32
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
struct timeval {
|
|
||||||
long tv_sec;
|
|
||||||
long tv_usec;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _FILETIME {
|
|
||||||
unsigned long dwLowDateTime;
|
|
||||||
unsigned long dwHighDateTime;
|
|
||||||
} FILETIME;
|
|
||||||
|
|
||||||
void __stdcall GetSystemTimeAsFileTime(FILETIME*);
|
|
||||||
|
|
||||||
//int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
|
|
||||||
|
|
||||||
int gettimeofday(struct timeval* p, void* tz /* IGNORED */) {
|
|
||||||
union {
|
|
||||||
long long ns100; /*time since 1 Jan 1601 in 100ns units */
|
|
||||||
FILETIME ft;
|
|
||||||
} _now;
|
|
||||||
|
|
||||||
if(!p)
|
|
||||||
return -1;
|
|
||||||
GetSystemTimeAsFileTime( &(_now.ft) );
|
|
||||||
p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL );
|
|
||||||
p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@@ -1,27 +0,0 @@
|
|||||||
/* $Id: wingettimeofday.h,v 1.1 2009/12/19 12:02:42 nanard Exp $ */
|
|
||||||
/* libnatpmp
|
|
||||||
* Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
|
|
||||||
* http://miniupnp.free.fr/libnatpmp.html
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
||||||
#ifndef __WINGETTIMEOFDAY_H__
|
|
||||||
#define __WINGETTIMEOFDAY_H__
|
|
||||||
#ifdef WIN32
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include <time.h>
|
|
||||||
#else
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@@ -1 +0,0 @@
|
|||||||
1.4
|
|
@@ -1,89 +0,0 @@
|
|||||||
import java.nio.ByteBuffer;
|
|
||||||
import fr.free.miniupnp.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author syuu
|
|
||||||
*/
|
|
||||||
public class JavaBridgeTest {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
int UPNP_DELAY = 2000;
|
|
||||||
MiniupnpcLibrary miniupnpc = MiniupnpcLibrary.INSTANCE;
|
|
||||||
UPNPDev devlist = null;
|
|
||||||
UPNPUrls urls = new UPNPUrls();
|
|
||||||
IGDdatas data = new IGDdatas();
|
|
||||||
ByteBuffer lanaddr = ByteBuffer.allocate(16);
|
|
||||||
ByteBuffer intClient = ByteBuffer.allocate(16);
|
|
||||||
ByteBuffer intPort = ByteBuffer.allocate(6);
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(args.length < 2) {
|
|
||||||
System.err.println("Usage : java [...] JavaBridgeTest port protocol");
|
|
||||||
System.out.println(" port is numeric, protocol is TCP or UDP");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
devlist = miniupnpc.upnpDiscover(UPNP_DELAY, (String) null, (String) null, 0);
|
|
||||||
if (devlist != null) {
|
|
||||||
System.out.println("List of UPNP devices found on the network :");
|
|
||||||
for (UPNPDev device = devlist; device != null; device = device.pNext) {
|
|
||||||
System.out.println("desc: " + device.descURL.getString(0) + " st: " + device.st.getString(0));
|
|
||||||
}
|
|
||||||
if ((i = miniupnpc.UPNP_GetValidIGD(devlist, urls, data, lanaddr, 16)) != 0) {
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
System.out.println("Found valid IGD : " + urls.controlURL.getString(0));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
System.out.println("Found a (not connected?) IGD : " + urls.controlURL.getString(0));
|
|
||||||
System.out.println("Trying to continue anyway");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
System.out.println("UPnP device found. Is it an IGD ? : " + urls.controlURL.getString(0));
|
|
||||||
System.out.println("Trying to continue anyway");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.out.println("Found device (igd ?) : " + urls.controlURL.getString(0));
|
|
||||||
System.out.println("Trying to continue anyway");
|
|
||||||
|
|
||||||
}
|
|
||||||
System.out.println("Local LAN ip address : " + new String(lanaddr.array()));
|
|
||||||
ByteBuffer externalAddress = ByteBuffer.allocate(16);
|
|
||||||
miniupnpc.UPNP_GetExternalIPAddress(urls.controlURL.getString(0),
|
|
||||||
new String(data.first.servicetype), externalAddress);
|
|
||||||
System.out.println("ExternalIPAddress = " + new String(externalAddress.array()));
|
|
||||||
ret = miniupnpc.UPNP_AddPortMapping(
|
|
||||||
urls.controlURL.getString(0), // controlURL
|
|
||||||
new String(data.first.servicetype), // servicetype
|
|
||||||
args[0], // external Port
|
|
||||||
args[0], // internal Port
|
|
||||||
new String(lanaddr.array()), // internal client
|
|
||||||
"added via miniupnpc/JAVA !", // description
|
|
||||||
args[1], // protocol UDP or TCP
|
|
||||||
null); // remote host (useless)
|
|
||||||
if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
|
|
||||||
System.out.println("AddPortMapping() failed with code " + ret);
|
|
||||||
ret = miniupnpc.UPNP_GetSpecificPortMappingEntry(
|
|
||||||
urls.controlURL.getString(0), new String(data.first.servicetype),
|
|
||||||
args[0], args[1], intClient, intPort);
|
|
||||||
if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
|
|
||||||
System.out.println("GetSpecificPortMappingEntry() failed with code " + ret);
|
|
||||||
System.out.println("InternalIP:Port = " +
|
|
||||||
new String(intClient.array()) + ":" + new String(intPort.array()));
|
|
||||||
ret = miniupnpc.UPNP_DeletePortMapping(
|
|
||||||
urls.controlURL.getString(0),
|
|
||||||
new String(data.first.servicetype),
|
|
||||||
args[0], args[1], null);
|
|
||||||
if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
|
|
||||||
System.out.println("DelPortMapping() failed with code " + ret);
|
|
||||||
miniupnpc.FreeUPNPUrls(urls);
|
|
||||||
} else {
|
|
||||||
System.out.println("No valid UPNP Internet Gateway Device found.");
|
|
||||||
}
|
|
||||||
miniupnpc.freeUPNPDevlist(devlist);
|
|
||||||
} else {
|
|
||||||
System.out.println("No IGD UPnP Device found on the network !\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
|
|
||||||
JAVA=java
|
|
||||||
JAVAC=javac
|
|
||||||
|
|
||||||
$JAVAC -cp miniupnpc_Linux.jar JavaBridgeTest.java
|
|
||||||
$JAVA -cp miniupnpc_Linux.jar:. JavaBridgeTest 12345 UDP
|
|
||||||
|
|
@@ -1,52 +0,0 @@
|
|||||||
\" $Id: miniupnpc.3,v 1.2 2008/10/07 13:51:55 nanard Exp $
|
|
||||||
.TH miniupnpc 3
|
|
||||||
.SH NAME
|
|
||||||
miniupnpc \- UPnP client library
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.SH DESCRIPTION
|
|
||||||
The miniupnpc library implement the UPnP protocol defined
|
|
||||||
to dialog with Internet Gateway Devices. It also has
|
|
||||||
the ability to use data gathered by minissdpd(1) about
|
|
||||||
UPnP devices up on the network in order to skip the
|
|
||||||
long UPnP device discovery process.
|
|
||||||
.PP
|
|
||||||
At first, upnpDiscover(3) has to be used to discover UPnP IGD present
|
|
||||||
on the network. Then UPNP_GetValidIGD(3) to select the right one.
|
|
||||||
Alternatively, UPNP_GetIGDFromUrl(3) could be used to bypass discovery
|
|
||||||
process if the root description url of the device to use is known.
|
|
||||||
Then all the UPNP_* functions can be used, such as
|
|
||||||
UPNP_GetConnectionTypeInfo(3), UPNP_AddPortMapping(3), etc...
|
|
||||||
.SH "HEADER FILES"
|
|
||||||
.IP miniupnpc.h
|
|
||||||
That's the main header file for the miniupnpc library API.
|
|
||||||
It contains all the functions and structures related to device discovery.
|
|
||||||
.IP upnpcommands.h
|
|
||||||
This header file contain the UPnP IGD methods that are accessible
|
|
||||||
through the miniupnpc API. The name of the C functions are matching
|
|
||||||
the UPnP methods names. ie: GetGenericPortMappingEntry is
|
|
||||||
UPNP_GetGenericPortMappingEntry.
|
|
||||||
.SH "API FUNCTIONS"
|
|
||||||
.IP "struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int sameport);"
|
|
||||||
execute the discovery process.
|
|
||||||
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.
|
|
||||||
.IP "void freeUPNPDevlist(struct UPNPDev * devlist);"
|
|
||||||
free the list returned by upnpDiscover().
|
|
||||||
.IP "int UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPUrls * urls, struct IGDdatas * data, char * lanaddr, int lanaddrlen);"
|
|
||||||
browse the list of device returned by upnpDiscover(), find
|
|
||||||
a live UPnP internet gateway device and fill structures passed as arguments
|
|
||||||
with data used for UPNP methods invokation.
|
|
||||||
.IP "int UPNP_GetIGDFromUrl(const char * rootdescurl, struct UPNPUrls * urls, struct IGDdatas * data, char * lanaddr, int lanaddrlen);"
|
|
||||||
permit to bypass the upnpDiscover() call if the xml root description
|
|
||||||
URL of the UPnP IGD is known.
|
|
||||||
Fill structures passed as arguments
|
|
||||||
with data used for UPNP methods invokation.
|
|
||||||
.IP "void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);"
|
|
||||||
.IP "void FreeUPNPUrls(struct UPNPUrls *);"
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
minissdpd(1)
|
|
||||||
.SH BUGS
|
|
@@ -1,274 +0,0 @@
|
|||||||
/* $Id: miniwget.c,v 1.37 2010/04/12 20:39:42 nanard Exp $ */
|
|
||||||
/* Project : miniupnp
|
|
||||||
* Author : Thomas Bernard
|
|
||||||
* Copyright (c) 2005-2010 Thomas Bernard
|
|
||||||
* This software is subject to the conditions detailed in the
|
|
||||||
* LICENCE file provided in this distribution. */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "miniupnpc.h"
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <io.h>
|
|
||||||
#define MAXHOSTNAMELEN 64
|
|
||||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#define socklen_t int
|
|
||||||
#else /* #ifdef WIN32 */
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#if defined(__amigaos__) && !defined(__amigaos4__)
|
|
||||||
#define socklen_t int
|
|
||||||
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#define closesocket close
|
|
||||||
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
|
||||||
* during the connect() call */
|
|
||||||
#define MINIUPNPC_IGNORE_EINTR
|
|
||||||
#endif /* #else WIN32 */
|
|
||||||
#if defined(__sun) || defined(sun)
|
|
||||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "miniupnpcstrings.h"
|
|
||||||
#include "miniwget.h"
|
|
||||||
#include "connecthostport.h"
|
|
||||||
|
|
||||||
/* miniwget3() :
|
|
||||||
* do all the work.
|
|
||||||
* Return NULL if something failed. */
|
|
||||||
static void *
|
|
||||||
miniwget3(const char * url, const char * host,
|
|
||||||
unsigned short port, const char * path,
|
|
||||||
int * size, char * addr_str, int addr_str_len, const char * httpversion)
|
|
||||||
{
|
|
||||||
char buf[2048];
|
|
||||||
int s;
|
|
||||||
int n;
|
|
||||||
int len;
|
|
||||||
int sent;
|
|
||||||
|
|
||||||
*size = 0;
|
|
||||||
s = connecthostport(host, port);
|
|
||||||
if(s < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* get address for caller ! */
|
|
||||||
if(addr_str)
|
|
||||||
{
|
|
||||||
struct sockaddr saddr;
|
|
||||||
socklen_t saddrlen;
|
|
||||||
|
|
||||||
saddrlen = sizeof(saddr);
|
|
||||||
if(getsockname(s, &saddr, &saddrlen) < 0)
|
|
||||||
{
|
|
||||||
perror("getsockname");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if defined(__amigaos__) && !defined(__amigaos4__)
|
|
||||||
/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
|
|
||||||
* But his function make a string with the port : nn.nn.nn.nn:port */
|
|
||||||
/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
|
|
||||||
NULL, addr_str, (DWORD *)&addr_str_len))
|
|
||||||
{
|
|
||||||
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
|
|
||||||
}*/
|
|
||||||
strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
|
|
||||||
#else
|
|
||||||
/*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
|
|
||||||
n = getnameinfo(&saddr, saddrlen,
|
|
||||||
addr_str, addr_str_len,
|
|
||||||
NULL, 0,
|
|
||||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
|
||||||
if(n != 0) {
|
|
||||||
#ifdef WIN32
|
|
||||||
fprintf(stderr, "getnameinfo() failed : %d\n", n);
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("address miniwget : %s\n", addr_str);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf),
|
|
||||||
"GET %s HTTP/%s\r\n"
|
|
||||||
"Host: %s:%d\r\n"
|
|
||||||
"Connection: Close\r\n"
|
|
||||||
"User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
|
|
||||||
|
|
||||||
"\r\n",
|
|
||||||
path, httpversion, host, port);
|
|
||||||
sent = 0;
|
|
||||||
/* sending the HTTP request */
|
|
||||||
while(sent < len)
|
|
||||||
{
|
|
||||||
n = send(s, buf+sent, len-sent, 0);
|
|
||||||
if(n < 0)
|
|
||||||
{
|
|
||||||
perror("send");
|
|
||||||
closesocket(s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sent += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
/* TODO : in order to support HTTP/1.1, chunked transfer encoding
|
|
||||||
* must be supported. That means parsing of headers must be
|
|
||||||
* added. */
|
|
||||||
int headers=1;
|
|
||||||
char * respbuffer = NULL;
|
|
||||||
int allreadyread = 0;
|
|
||||||
/*while((n = recv(s, buf, 2048, 0)) > 0)*/
|
|
||||||
while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
|
|
||||||
{
|
|
||||||
if(headers)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
while(i<n-3)
|
|
||||||
{
|
|
||||||
/* searching for the end of the HTTP headers */
|
|
||||||
if(buf[i]=='\r' && buf[i+1]=='\n'
|
|
||||||
&& buf[i+2]=='\r' && buf[i+3]=='\n')
|
|
||||||
{
|
|
||||||
headers = 0; /* end */
|
|
||||||
if(i<n-4)
|
|
||||||
{
|
|
||||||
/* Copy the content into respbuffet */
|
|
||||||
respbuffer = (char *)realloc((void *)respbuffer,
|
|
||||||
allreadyread+(n-i-4));
|
|
||||||
memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
|
|
||||||
allreadyread += (n-i-4);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
respbuffer = (char *)realloc((void *)respbuffer,
|
|
||||||
allreadyread+n);
|
|
||||||
memcpy(respbuffer+allreadyread, buf, n);
|
|
||||||
allreadyread += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*size = allreadyread;
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("%d bytes read\n", *size);
|
|
||||||
#endif
|
|
||||||
closesocket(s);
|
|
||||||
return respbuffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* miniwget2() :
|
|
||||||
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
|
|
||||||
static void *
|
|
||||||
miniwget2(const char * url, const char * host,
|
|
||||||
unsigned short port, const char * path,
|
|
||||||
int * size, char * addr_str, int addr_str_len)
|
|
||||||
{
|
|
||||||
char * respbuffer;
|
|
||||||
|
|
||||||
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
|
|
||||||
if (*size == 0)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Retrying with HTTP/1.1\n");
|
|
||||||
#endif
|
|
||||||
free(respbuffer);
|
|
||||||
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
|
|
||||||
}
|
|
||||||
return respbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* parseURL()
|
|
||||||
* arguments :
|
|
||||||
* url : source string not modified
|
|
||||||
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
|
|
||||||
* port : port (destination)
|
|
||||||
* path : pointer to the path part of the URL
|
|
||||||
*
|
|
||||||
* Return values :
|
|
||||||
* 0 - Failure
|
|
||||||
* 1 - Success */
|
|
||||||
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
|
|
||||||
{
|
|
||||||
char * p1, *p2, *p3;
|
|
||||||
p1 = strstr(url, "://");
|
|
||||||
if(!p1)
|
|
||||||
return 0;
|
|
||||||
p1 += 3;
|
|
||||||
if( (url[0]!='h') || (url[1]!='t')
|
|
||||||
||(url[2]!='t') || (url[3]!='p'))
|
|
||||||
return 0;
|
|
||||||
p2 = strchr(p1, ':');
|
|
||||||
p3 = strchr(p1, '/');
|
|
||||||
if(!p3)
|
|
||||||
return 0;
|
|
||||||
memset(hostname, 0, MAXHOSTNAMELEN + 1);
|
|
||||||
if(!p2 || (p2>p3))
|
|
||||||
{
|
|
||||||
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
|
|
||||||
*port = 80;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
|
|
||||||
*port = 0;
|
|
||||||
p2++;
|
|
||||||
while( (*p2 >= '0') && (*p2 <= '9'))
|
|
||||||
{
|
|
||||||
*port *= 10;
|
|
||||||
*port += (unsigned short)(*p2 - '0');
|
|
||||||
p2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*path = p3;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * miniwget(const char * url, int * size)
|
|
||||||
{
|
|
||||||
unsigned short port;
|
|
||||||
char * path;
|
|
||||||
/* protocol://host:port/chemin */
|
|
||||||
char hostname[MAXHOSTNAMELEN+1];
|
|
||||||
*size = 0;
|
|
||||||
if(!parseURL(url, hostname, &port, &path))
|
|
||||||
return NULL;
|
|
||||||
return miniwget2(url, hostname, port, path, size, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
|
|
||||||
{
|
|
||||||
unsigned short port;
|
|
||||||
char * path;
|
|
||||||
/* protocol://host:port/chemin */
|
|
||||||
char hostname[MAXHOSTNAMELEN+1];
|
|
||||||
*size = 0;
|
|
||||||
if(addr)
|
|
||||||
addr[0] = '\0';
|
|
||||||
if(!parseURL(url, hostname, &port, &path))
|
|
||||||
return NULL;
|
|
||||||
return miniwget2(url, hostname, port, path, size, addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
@@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
|
||||||
# Visual C++ Express 2008
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "miniupnpc.vcproj", "{D28CE435-CB33-4BAE-8A52-C6EF915956F5}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upnpc-static", "upnpc-static.vcproj", "{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{D28CE435-CB33-4BAE-8A52-C6EF915956F5} = {D28CE435-CB33-4BAE-8A52-C6EF915956F5}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
@@ -1,251 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9,00"
|
|
||||||
Name="miniupnpc"
|
|
||||||
ProjectGUID="{D28CE435-CB33-4BAE-8A52-C6EF915956F5}"
|
|
||||||
RootNamespace="miniupnpc"
|
|
||||||
Keyword="Win32Proj"
|
|
||||||
TargetFrameworkVersion="196613"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="4"
|
|
||||||
CharacterSet="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;WIN32;STATICLIB;DEBUG"
|
|
||||||
MinimalRebuild="true"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="3"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLibrarianTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="4"
|
|
||||||
CharacterSet="1"
|
|
||||||
WholeProgramOptimization="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;WIN32;STATICLIB"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLibrarianTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers sources"
|
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\connecthostport.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\igd_desc_parse.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\minisoap.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\miniupnpc.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\miniwget.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\minixml.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnpcommands.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnperrors.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnpreplyparse.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers d'en-t<>te"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\bsdqueue.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\connecthostport.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\declspec.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\igd_desc_parse.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\minisoap.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\miniupnpc.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\miniupnpcstrings.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\miniwget.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\minixml.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnpcommands.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnperrors.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnpreplyparse.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers de ressources"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@@ -1,195 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9,00"
|
|
||||||
Name="upnpc-static"
|
|
||||||
ProjectGUID="{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}"
|
|
||||||
RootNamespace="upnpcstatic"
|
|
||||||
Keyword="Win32Proj"
|
|
||||||
TargetFrameworkVersion="196613"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;STATICLIB;DEBUG;_CRT_SECURE_NO_WARNINGS"
|
|
||||||
MinimalRebuild="true"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="3"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="ws2_32.lib IPHlpApi.Lib Debug\miniupnpc.lib"
|
|
||||||
LinkIncremental="2"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="1"
|
|
||||||
WholeProgramOptimization="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;STATICLIB"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="ws2_32.lib IPHlpApi.Lib Release\miniupnpc.lib"
|
|
||||||
LinkIncremental="1"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers sources"
|
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\upnpc.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers d'en-t<>te"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Fichiers de ressources"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@@ -1,52 +0,0 @@
|
|||||||
#! /usr/bin/python
|
|
||||||
# MiniUPnP project
|
|
||||||
# Author : Thomas Bernard
|
|
||||||
# This Sample code is public domain.
|
|
||||||
# website : http://miniupnp.tuxfamily.org/
|
|
||||||
|
|
||||||
# import the python miniupnpc module
|
|
||||||
import miniupnpc
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# create the object
|
|
||||||
u = miniupnpc.UPnP()
|
|
||||||
print 'inital(default) values :'
|
|
||||||
print ' discoverdelay', u.discoverdelay
|
|
||||||
print ' lanaddr', u.lanaddr
|
|
||||||
print ' multicastif', u.multicastif
|
|
||||||
print ' minissdpdsocket', u.minissdpdsocket
|
|
||||||
u.discoverdelay = 200;
|
|
||||||
#u.minissdpdsocket = '../minissdpd/minissdpd.sock'
|
|
||||||
# discovery process, it usualy takes several seconds (2 seconds or more)
|
|
||||||
print 'Discovering... delay=%ums' % u.discoverdelay
|
|
||||||
print u.discover(), 'device(s) detected'
|
|
||||||
# select an igd
|
|
||||||
try:
|
|
||||||
u.selectigd()
|
|
||||||
except Exception, e:
|
|
||||||
print 'Exception :', e
|
|
||||||
sys.exit(1)
|
|
||||||
# display information about the IGD and the internet connection
|
|
||||||
print 'local ip address :', u.lanaddr
|
|
||||||
print 'external ip address :', u.externalipaddress()
|
|
||||||
print u.statusinfo(), u.connectiontype()
|
|
||||||
|
|
||||||
#print u.addportmapping(64000, 'TCP',
|
|
||||||
# '192.168.1.166', 63000, 'port mapping test', '')
|
|
||||||
#print u.deleteportmapping(64000, 'TCP')
|
|
||||||
|
|
||||||
port = 0
|
|
||||||
proto = 'UDP'
|
|
||||||
# list the redirections :
|
|
||||||
i = 0
|
|
||||||
while True:
|
|
||||||
p = u.getgenericportmapping(i)
|
|
||||||
if p==None:
|
|
||||||
break
|
|
||||||
print i, p
|
|
||||||
(port, proto, (ihost,iport), desc, c, d, e) = p
|
|
||||||
#print port, desc
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
print u.getspecificportmapping(port, proto)
|
|
||||||
|
|
@@ -1,15 +0,0 @@
|
|||||||
#! /usr/bin/python
|
|
||||||
# $Id: setup.py,v 1.5 2009/10/30 09:18:18 nanard Exp $
|
|
||||||
# the MiniUPnP Project (c) 2007-2009 Thomas Bernard
|
|
||||||
# http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
|
|
||||||
#
|
|
||||||
# python script to build the miniupnpc module under unix
|
|
||||||
#
|
|
||||||
# replace libminiupnpc.a by libminiupnpc.so for shared library usage
|
|
||||||
from distutils.core import setup, Extension
|
|
||||||
setup(name="miniupnpc", version="1.4",
|
|
||||||
ext_modules=[
|
|
||||||
Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
|
|
||||||
extra_objects=["libminiupnpc.a"])
|
|
||||||
])
|
|
||||||
|
|
@@ -1,15 +0,0 @@
|
|||||||
#! /usr/bin/python
|
|
||||||
# $Id: setupmingw32.py,v 1.3 2009/10/30 09:18:18 nanard Exp $
|
|
||||||
# the MiniUPnP Project (c) 2007-2009 Thomas Bernard
|
|
||||||
# http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
|
|
||||||
#
|
|
||||||
# python script to build the miniupnpc module under unix
|
|
||||||
#
|
|
||||||
from distutils.core import setup, Extension
|
|
||||||
setup(name="miniupnpc", version="1.4",
|
|
||||||
ext_modules=[
|
|
||||||
Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
|
|
||||||
libraries=["ws2_32"],
|
|
||||||
extra_objects=["libminiupnpc.a"])
|
|
||||||
])
|
|
||||||
|
|
@@ -1,64 +0,0 @@
|
|||||||
/* $Id: testigddescparse.c,v 1.2 2009/12/03 13:50:06 nanard Exp $ */
|
|
||||||
/* Project : miniupnp
|
|
||||||
* http://miniupnp.free.fr/
|
|
||||||
* Author : Thomas Bernard
|
|
||||||
* Copyright (c) 2008-2009 Thomas Bernard
|
|
||||||
* This software is subject to the conditions detailed in the
|
|
||||||
* LICENCE file provided in this distribution.
|
|
||||||
* */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "igd_desc_parse.h"
|
|
||||||
#include "minixml.h"
|
|
||||||
#include "miniupnpc.h"
|
|
||||||
|
|
||||||
int test_igd_desc_parse(char * buffer, int len)
|
|
||||||
{
|
|
||||||
struct IGDdatas igd;
|
|
||||||
struct xmlparser parser;
|
|
||||||
struct UPNPUrls urls;
|
|
||||||
memset(&igd, 0, sizeof(struct IGDdatas));
|
|
||||||
memset(&parser, 0, sizeof(struct xmlparser));
|
|
||||||
parser.xmlstart = buffer;
|
|
||||||
parser.xmlsize = len;
|
|
||||||
parser.data = &igd;
|
|
||||||
parser.starteltfunc = IGDstartelt;
|
|
||||||
parser.endeltfunc = IGDendelt;
|
|
||||||
parser.datafunc = IGDdata;
|
|
||||||
parsexml(&parser);
|
|
||||||
printIGD(&igd);
|
|
||||||
GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml");
|
|
||||||
printf("ipcondescURL='%s'\n", urls.ipcondescURL);
|
|
||||||
printf("controlURL='%s'\n", urls.controlURL);
|
|
||||||
printf("controlURL_CIF='%s'\n", urls.controlURL_CIF);
|
|
||||||
FreeUPNPUrls(&urls);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char * * argv)
|
|
||||||
{
|
|
||||||
FILE * f;
|
|
||||||
char * buffer;
|
|
||||||
int len;
|
|
||||||
int r = 0;
|
|
||||||
if(argc<2) {
|
|
||||||
fprintf(stderr, "Usage: %s file.xml\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
f = fopen(argv[1], "r");
|
|
||||||
if(!f) {
|
|
||||||
fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
len = ftell(f);
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
buffer = malloc(len);
|
|
||||||
fread(buffer, 1, len, f);
|
|
||||||
fclose(f);
|
|
||||||
r = test_igd_desc_parse(buffer, len);
|
|
||||||
free(buffer);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,45 +0,0 @@
|
|||||||
/* $Id: testminiwget.c,v 1.1 2009/12/03 18:44:32 nanard Exp $ */
|
|
||||||
/* Project : miniupnp
|
|
||||||
* Author : Thomas Bernard
|
|
||||||
* Copyright (c) 2005-2009 Thomas Bernard
|
|
||||||
* This software is subject to the conditions detailed in the
|
|
||||||
* LICENCE file provided in this distribution.
|
|
||||||
* */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "miniwget.h"
|
|
||||||
|
|
||||||
int main(int argc, char * * argv)
|
|
||||||
{
|
|
||||||
void * data;
|
|
||||||
int size, writtensize;
|
|
||||||
FILE *f;
|
|
||||||
if(argc < 3) {
|
|
||||||
fprintf(stderr, "Usage:\t%s url file\n", argv[0]);
|
|
||||||
fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
data = miniwget(argv[1], &size);
|
|
||||||
if(!data) {
|
|
||||||
fprintf(stderr, "Error fetching %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("got %d bytes\n", size);
|
|
||||||
f = fopen(argv[2], "wb");
|
|
||||||
if(!f) {
|
|
||||||
fprintf(stderr, "Cannot open file %s for writing\n", argv[2]);
|
|
||||||
free(data);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
writtensize = fwrite(data, 1, size, f);
|
|
||||||
if(writtensize != size) {
|
|
||||||
fprintf(stderr, "Could only write %d bytes out of %d to %s\n",
|
|
||||||
writtensize, size, argv[2]);
|
|
||||||
} else {
|
|
||||||
printf("%d bytes written to %s\n", writtensize, argv[2]);
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
free(data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,88 +0,0 @@
|
|||||||
/* $Id: testminixml.c,v 1.6 2006/11/19 22:32:35 nanard Exp $
|
|
||||||
* testminixml.c
|
|
||||||
* test program for the "minixml" functions.
|
|
||||||
* Author : Thomas Bernard.
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "minixml.h"
|
|
||||||
#include "igd_desc_parse.h"
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#define NO_BZERO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NO_BZERO
|
|
||||||
#define bzero(p, n) memset(p, 0, n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
void printeltname1(void * d, const char * name, int l)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
printf("element ");
|
|
||||||
for(i=0;i<l;i++)
|
|
||||||
putchar(name[i]);
|
|
||||||
}
|
|
||||||
void printeltname2(void * d, const char * name, int l)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
putchar('/');
|
|
||||||
for(i=0;i<l;i++)
|
|
||||||
putchar(name[i]);
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
void printdata(void *d, const char * data, int l)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
printf("data : ");
|
|
||||||
for(i=0;i<l;i++)
|
|
||||||
putchar(data[i]);
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
void burptest(const char * buffer, int bufsize)
|
|
||||||
{
|
|
||||||
struct IGDdatas data;
|
|
||||||
struct xmlparser parser;
|
|
||||||
/*objet IGDdatas */
|
|
||||||
bzero(&data, sizeof(struct IGDdatas));
|
|
||||||
/* objet xmlparser */
|
|
||||||
parser.xmlstart = buffer;
|
|
||||||
parser.xmlsize = bufsize;
|
|
||||||
parser.data = &data;
|
|
||||||
/*parser.starteltfunc = printeltname1;
|
|
||||||
parser.endeltfunc = printeltname2;
|
|
||||||
parser.datafunc = printdata; */
|
|
||||||
parser.starteltfunc = IGDstartelt;
|
|
||||||
parser.endeltfunc = IGDendelt;
|
|
||||||
parser.datafunc = IGDdata;
|
|
||||||
parsexml(&parser);
|
|
||||||
printIGD(&data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----- main ---- */
|
|
||||||
#define XML_MAX_SIZE (8192)
|
|
||||||
int main(int argc, char * * argv)
|
|
||||||
{
|
|
||||||
FILE * f;
|
|
||||||
char buffer[XML_MAX_SIZE];
|
|
||||||
int bufsize;
|
|
||||||
if(argc<2)
|
|
||||||
{
|
|
||||||
printf("usage:\t%s file.xml\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
f = fopen(argv[1], "r");
|
|
||||||
if(!f)
|
|
||||||
{
|
|
||||||
printf("cannot open file %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bufsize = (int)fread(buffer, 1, XML_MAX_SIZE, f);
|
|
||||||
fclose(f);
|
|
||||||
burptest(buffer, bufsize);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,84 +0,0 @@
|
|||||||
#! /usr/bin/python
|
|
||||||
# $Id: testupnpigd.py,v 1.4 2008/10/11 10:27:20 nanard Exp $
|
|
||||||
# MiniUPnP project
|
|
||||||
# Author : Thomas Bernard
|
|
||||||
# This Sample code is public domain.
|
|
||||||
# website : http://miniupnp.tuxfamily.org/
|
|
||||||
|
|
||||||
# import the python miniupnpc module
|
|
||||||
import miniupnpc
|
|
||||||
import socket
|
|
||||||
import BaseHTTPServer
|
|
||||||
|
|
||||||
# function definition
|
|
||||||
def list_redirections():
|
|
||||||
i = 0
|
|
||||||
while True:
|
|
||||||
p = u.getgenericportmapping(i)
|
|
||||||
if p==None:
|
|
||||||
break
|
|
||||||
print i, p
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
#define the handler class for HTTP connections
|
|
||||||
class handler_class(BaseHTTPServer.BaseHTTPRequestHandler):
|
|
||||||
def do_GET(self):
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write("OK MON GARS")
|
|
||||||
|
|
||||||
# create the object
|
|
||||||
u = miniupnpc.UPnP()
|
|
||||||
#print 'inital(default) values :'
|
|
||||||
#print ' discoverdelay', u.discoverdelay
|
|
||||||
#print ' lanaddr', u.lanaddr
|
|
||||||
#print ' multicastif', u.multicastif
|
|
||||||
#print ' minissdpdsocket', u.minissdpdsocket
|
|
||||||
u.discoverdelay = 200;
|
|
||||||
|
|
||||||
try:
|
|
||||||
print 'Discovering... delay=%ums' % u.discoverdelay
|
|
||||||
ndevices = u.discover()
|
|
||||||
print ndevices, 'device(s) detected'
|
|
||||||
|
|
||||||
# select an igd
|
|
||||||
u.selectigd()
|
|
||||||
# display information about the IGD and the internet connection
|
|
||||||
print 'local ip address :', u.lanaddr
|
|
||||||
externalipaddress = u.externalipaddress()
|
|
||||||
print 'external ip address :', externalipaddress
|
|
||||||
print u.statusinfo(), u.connectiontype()
|
|
||||||
|
|
||||||
#instanciate a HTTPd object. The port is assigned by the system.
|
|
||||||
httpd = BaseHTTPServer.HTTPServer((u.lanaddr, 0), handler_class)
|
|
||||||
eport = httpd.server_port
|
|
||||||
|
|
||||||
# find a free port for the redirection
|
|
||||||
r = u.getspecificportmapping(eport, 'TCP')
|
|
||||||
while r != None and eport < 65536:
|
|
||||||
eport = eport + 1
|
|
||||||
r = u.getspecificportmapping(eport, 'TCP')
|
|
||||||
|
|
||||||
print 'trying to redirect %s port %u TCP => %s port %u TCP' % (externalipaddress, eport, u.lanaddr, httpd.server_port)
|
|
||||||
|
|
||||||
b = u.addportmapping(eport, 'TCP', u.lanaddr, httpd.server_port,
|
|
||||||
'UPnP IGD Tester port %u' % eport, '')
|
|
||||||
if b:
|
|
||||||
print 'Success. Now waiting for some HTTP request on http://%s:%u' % (externalipaddress ,eport)
|
|
||||||
try:
|
|
||||||
httpd.handle_request()
|
|
||||||
httpd.server_close()
|
|
||||||
except KeyboardInterrupt, details:
|
|
||||||
print "CTRL-C exception!", details
|
|
||||||
b = u.deleteportmapping(eport, 'TCP')
|
|
||||||
if b:
|
|
||||||
print 'Successfully deleted port mapping'
|
|
||||||
else:
|
|
||||||
print 'Failed to remove port mapping'
|
|
||||||
else:
|
|
||||||
print 'Failed'
|
|
||||||
|
|
||||||
httpd.server_close()
|
|
||||||
|
|
||||||
except Exception, e:
|
|
||||||
print 'Exception :', e
|
|
@@ -1,44 +0,0 @@
|
|||||||
/* $Id: testupnpreplyparse.c,v 1.2 2008/02/21 13:05:27 nanard Exp $ */
|
|
||||||
/* MiniUPnP project
|
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
|
||||||
* (c) 2006-2007 Thomas Bernard
|
|
||||||
* This software is subject to the conditions detailed
|
|
||||||
* in the LICENCE file provided within the distribution */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "upnpreplyparse.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
test_parsing(const char * buf, int len)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
ParseNameValue(buf, len, &pdata);
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char * * argv)
|
|
||||||
{
|
|
||||||
FILE * f;
|
|
||||||
char buffer[4096];
|
|
||||||
int l;
|
|
||||||
if(argc<2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: %s file.xml\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
f = fopen(argv[1], "r");
|
|
||||||
if(!f)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error : can not open file %s\n", argv[1]);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
l = fread(buffer, 1, sizeof(buffer)-1, f);
|
|
||||||
fclose(f);
|
|
||||||
buffer[l] = '\0';
|
|
||||||
#ifdef DEBUG
|
|
||||||
DisplayNameValueList(buffer, l);
|
|
||||||
#endif
|
|
||||||
test_parsing(buffer, l);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,45 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# $Id: updateminiupnpcstrings.sh,v 1.6 2009/12/07 11:29:57 nanard Exp $
|
|
||||||
# project miniupnp : http://miniupnp.free.fr/
|
|
||||||
# (c) 2009 Thomas Bernard
|
|
||||||
|
|
||||||
FILE=miniupnpcstrings.h
|
|
||||||
TEMPLATE_FILE=${FILE}.in
|
|
||||||
|
|
||||||
# detecting the OS name and version
|
|
||||||
OS_NAME=`uname -s`
|
|
||||||
OS_VERSION=`uname -r`
|
|
||||||
if [ -f /etc/debian_version ]; then
|
|
||||||
OS_NAME=Debian
|
|
||||||
OS_VERSION=`cat /etc/debian_version`
|
|
||||||
fi
|
|
||||||
# use lsb_release (Linux Standard Base) when available
|
|
||||||
LSB_RELEASE=`which lsb_release`
|
|
||||||
if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then
|
|
||||||
OS_NAME=`${LSB_RELEASE} -i -s`
|
|
||||||
OS_VERSION=`${LSB_RELEASE} -r -s`
|
|
||||||
case $OS_NAME in
|
|
||||||
Debian)
|
|
||||||
#OS_VERSION=`${LSB_RELEASE} -c -s`
|
|
||||||
;;
|
|
||||||
Ubuntu)
|
|
||||||
#OS_VERSION=`${LSB_RELEASE} -c -s`
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# on AmigaOS 3, uname -r returns "unknown", so we use uname -v
|
|
||||||
if [ "$OS_NAME" = "AmigaOS" ]; then
|
|
||||||
if [ "$OS_VERSION" = "unknown" ]; then
|
|
||||||
OS_VERSION=`uname -v`
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Detected OS [$OS_NAME] version [$OS_VERSION]"
|
|
||||||
|
|
||||||
EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|"
|
|
||||||
#echo $EXPR
|
|
||||||
test -f ${FILE}.in
|
|
||||||
echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE."
|
|
||||||
sed -e "$EXPR" < $TEMPLATE_FILE > $FILE
|
|
||||||
|
|
@@ -1,385 +0,0 @@
|
|||||||
/* $Id: upnpc.c,v 1.72 2010/05/29 09:21:12 nanard Exp $ */
|
|
||||||
/* Project : miniupnp
|
|
||||||
* Author : Thomas Bernard
|
|
||||||
* Copyright (c) 2005-2010 Thomas Bernard
|
|
||||||
* This software is subject to the conditions detailed in the
|
|
||||||
* LICENCE file provided in this distribution. */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#endif
|
|
||||||
#include "miniwget.h"
|
|
||||||
#include "miniupnpc.h"
|
|
||||||
#include "upnpcommands.h"
|
|
||||||
#include "upnperrors.h"
|
|
||||||
|
|
||||||
/* protofix() checks if protocol is "UDP" or "TCP"
|
|
||||||
* returns NULL if not */
|
|
||||||
const char * protofix(const char * proto)
|
|
||||||
{
|
|
||||||
static const char proto_tcp[4] = { 'T', 'C', 'P', 0};
|
|
||||||
static const char proto_udp[4] = { 'U', 'D', 'P', 0};
|
|
||||||
int i, b;
|
|
||||||
for(i=0, b=1; i<4; i++)
|
|
||||||
b = b && ( (proto[i] == proto_tcp[i])
|
|
||||||
|| (proto[i] == (proto_tcp[i] | 32)) );
|
|
||||||
if(b)
|
|
||||||
return proto_tcp;
|
|
||||||
for(i=0, b=1; i<4; i++)
|
|
||||||
b = b && ( (proto[i] == proto_udp[i])
|
|
||||||
|| (proto[i] == (proto_udp[i] | 32)) );
|
|
||||||
if(b)
|
|
||||||
return proto_udp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DisplayInfos(struct UPNPUrls * urls,
|
|
||||||
struct IGDdatas * data)
|
|
||||||
{
|
|
||||||
char externalIPAddress[16];
|
|
||||||
char connectionType[64];
|
|
||||||
char status[64];
|
|
||||||
char lastconnerr[64];
|
|
||||||
unsigned int uptime;
|
|
||||||
unsigned int brUp, brDown;
|
|
||||||
time_t timenow, timestarted;
|
|
||||||
int r;
|
|
||||||
UPNP_GetConnectionTypeInfo(urls->controlURL,
|
|
||||||
data->first.servicetype,
|
|
||||||
connectionType);
|
|
||||||
if(connectionType[0])
|
|
||||||
printf("Connection Type : %s\n", connectionType);
|
|
||||||
else
|
|
||||||
printf("GetConnectionTypeInfo failed.\n");
|
|
||||||
UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
|
|
||||||
status, &uptime, lastconnerr);
|
|
||||||
printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
|
|
||||||
status, uptime, lastconnerr);
|
|
||||||
timenow = time(NULL);
|
|
||||||
timestarted = timenow - uptime;
|
|
||||||
printf(" Time started : %s", ctime(×tarted));
|
|
||||||
UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
|
|
||||||
&brDown, &brUp);
|
|
||||||
printf("MaxBitRateDown : %u bps MaxBitRateUp %u bps\n", brDown, brUp);
|
|
||||||
r = UPNP_GetExternalIPAddress(urls->controlURL,
|
|
||||||
data->first.servicetype,
|
|
||||||
externalIPAddress);
|
|
||||||
if(r != UPNPCOMMAND_SUCCESS)
|
|
||||||
printf("GetExternalIPAddress() returned %d\n", r);
|
|
||||||
if(externalIPAddress[0])
|
|
||||||
printf("ExternalIPAddress = %s\n", externalIPAddress);
|
|
||||||
else
|
|
||||||
printf("GetExternalIPAddress failed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GetConnectionStatus(struct UPNPUrls * urls,
|
|
||||||
struct IGDdatas * data)
|
|
||||||
{
|
|
||||||
unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
|
|
||||||
DisplayInfos(urls, data);
|
|
||||||
bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
|
|
||||||
bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
|
|
||||||
packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
|
|
||||||
packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
|
|
||||||
printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
|
|
||||||
printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ListRedirections(struct UPNPUrls * urls,
|
|
||||||
struct IGDdatas * data)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
int i = 0;
|
|
||||||
char index[6];
|
|
||||||
char intClient[16];
|
|
||||||
char intPort[6];
|
|
||||||
char extPort[6];
|
|
||||||
char protocol[4];
|
|
||||||
char desc[80];
|
|
||||||
char enabled[6];
|
|
||||||
char rHost[64];
|
|
||||||
char duration[16];
|
|
||||||
/*unsigned int num=0;
|
|
||||||
UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
|
|
||||||
printf("PortMappingNumberOfEntries : %u\n", num);*/
|
|
||||||
do {
|
|
||||||
snprintf(index, 6, "%d", i);
|
|
||||||
rHost[0] = '\0'; enabled[0] = '\0';
|
|
||||||
duration[0] = '\0'; desc[0] = '\0';
|
|
||||||
extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
|
|
||||||
r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
|
|
||||||
data->first.servicetype,
|
|
||||||
index,
|
|
||||||
extPort, intClient, intPort,
|
|
||||||
protocol, desc, enabled,
|
|
||||||
rHost, duration);
|
|
||||||
if(r==0)
|
|
||||||
/*
|
|
||||||
printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n"
|
|
||||||
" desc='%s' rHost='%s'\n",
|
|
||||||
i, protocol, extPort, intClient, intPort,
|
|
||||||
enabled, duration,
|
|
||||||
desc, rHost);
|
|
||||||
*/
|
|
||||||
printf("%2d %s %5s->%s:%-5s '%s' '%s'\n",
|
|
||||||
i, protocol, extPort, intClient, intPort,
|
|
||||||
desc, rHost);
|
|
||||||
else
|
|
||||||
printf("GetGenericPortMappingEntry() returned %d (%s)\n",
|
|
||||||
r, strupnperror(r));
|
|
||||||
i++;
|
|
||||||
} while(r==0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test function
|
|
||||||
* 1 - get connection type
|
|
||||||
* 2 - get extenal ip address
|
|
||||||
* 3 - Add port mapping
|
|
||||||
* 4 - get this port mapping from the IGD */
|
|
||||||
static void SetRedirectAndTest(struct UPNPUrls * urls,
|
|
||||||
struct IGDdatas * data,
|
|
||||||
const char * iaddr,
|
|
||||||
const char * iport,
|
|
||||||
const char * eport,
|
|
||||||
const char * proto)
|
|
||||||
{
|
|
||||||
char externalIPAddress[16];
|
|
||||||
char intClient[16];
|
|
||||||
char intPort[6];
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if(!iaddr || !iport || !eport || !proto)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Wrong arguments\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
proto = protofix(proto);
|
|
||||||
if(!proto)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "invalid protocol\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UPNP_GetExternalIPAddress(urls->controlURL,
|
|
||||||
data->first.servicetype,
|
|
||||||
externalIPAddress);
|
|
||||||
if(externalIPAddress[0])
|
|
||||||
printf("ExternalIPAddress = %s\n", externalIPAddress);
|
|
||||||
else
|
|
||||||
printf("GetExternalIPAddress failed.\n");
|
|
||||||
|
|
||||||
r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
|
|
||||||
eport, iport, iaddr, 0, proto, 0);
|
|
||||||
if(r!=UPNPCOMMAND_SUCCESS)
|
|
||||||
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
|
||||||
eport, iport, iaddr, r, strupnperror(r));
|
|
||||||
|
|
||||||
r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
|
|
||||||
data->first.servicetype,
|
|
||||||
eport, proto,
|
|
||||||
intClient, intPort);
|
|
||||||
if(r!=UPNPCOMMAND_SUCCESS)
|
|
||||||
printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
|
|
||||||
r, strupnperror(r));
|
|
||||||
|
|
||||||
if(intClient[0]) {
|
|
||||||
printf("InternalIP:Port = %s:%s\n", intClient, intPort);
|
|
||||||
printf("external %s:%s %s is redirected to internal %s:%s\n",
|
|
||||||
externalIPAddress, eport, proto, intClient, intPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
RemoveRedirect(struct UPNPUrls * urls,
|
|
||||||
struct IGDdatas * data,
|
|
||||||
const char * eport,
|
|
||||||
const char * proto)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
if(!proto || !eport)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "invalid arguments\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
proto = protofix(proto);
|
|
||||||
if(!proto)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "protocol invalid\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0);
|
|
||||||
printf("UPNP_DeletePortMapping() returned : %d\n", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* sample upnp client program */
|
|
||||||
int main(int argc, char ** argv)
|
|
||||||
{
|
|
||||||
char command = 0;
|
|
||||||
char ** commandargv = 0;
|
|
||||||
int commandargc = 0;
|
|
||||||
struct UPNPDev * devlist = 0;
|
|
||||||
char lanaddr[64]; /* my ip address on the LAN */
|
|
||||||
int i;
|
|
||||||
const char * rootdescurl = 0;
|
|
||||||
const char * multicastif = 0;
|
|
||||||
const char * minissdpdpath = 0;
|
|
||||||
int retcode = 0;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
WSADATA wsaData;
|
|
||||||
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
|
||||||
if(nResult != NO_ERROR)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WSAStartup() failed.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
printf("upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard\n");
|
|
||||||
printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
|
|
||||||
"for more information.\n");
|
|
||||||
/* command line processing */
|
|
||||||
for(i=1; i<argc; i++)
|
|
||||||
{
|
|
||||||
if(argv[i][0] == '-')
|
|
||||||
{
|
|
||||||
if(argv[i][1] == 'u')
|
|
||||||
rootdescurl = argv[++i];
|
|
||||||
else if(argv[i][1] == 'm')
|
|
||||||
multicastif = argv[++i];
|
|
||||||
else if(argv[i][1] == 'p')
|
|
||||||
minissdpdpath = argv[++i];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
command = argv[i][1];
|
|
||||||
i++;
|
|
||||||
commandargv = argv + i;
|
|
||||||
commandargc = argc - i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "option '%s' invalid\n", argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!command || (command == 'a' && commandargc<4)
|
|
||||||
|| (command == 'd' && argc<2)
|
|
||||||
|| (command == 'r' && argc<2))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol\n\t\tAdd port redirection\n", argv[0]);
|
|
||||||
fprintf(stderr, " \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
|
|
||||||
fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
|
|
||||||
fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]);
|
|
||||||
fprintf(stderr, " \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
|
|
||||||
fprintf(stderr, "\nprotocol is UDP or TCP\n");
|
|
||||||
fprintf(stderr, "Options:\n");
|
|
||||||
fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n");
|
|
||||||
fprintf(stderr, " -m address : provide ip address of the interface to use for sending SSDP multicast packets.\n");
|
|
||||||
fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( rootdescurl
|
|
||||||
|| (devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0)))
|
|
||||||
{
|
|
||||||
struct UPNPDev * device;
|
|
||||||
struct UPNPUrls urls;
|
|
||||||
struct IGDdatas data;
|
|
||||||
if(devlist)
|
|
||||||
{
|
|
||||||
printf("List of UPNP devices found on the network :\n");
|
|
||||||
for(device = devlist; device; device = device->pNext)
|
|
||||||
{
|
|
||||||
printf(" desc: %s\n st: %s\n\n",
|
|
||||||
device->descURL, device->st);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = 1;
|
|
||||||
if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
|
|
||||||
|| (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
|
|
||||||
{
|
|
||||||
switch(i) {
|
|
||||||
case 1:
|
|
||||||
printf("Found valid IGD : %s\n", urls.controlURL);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
|
|
||||||
printf("Trying to continue anyway\n");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
|
|
||||||
printf("Trying to continue anyway\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Found device (igd ?) : %s\n", urls.controlURL);
|
|
||||||
printf("Trying to continue anyway\n");
|
|
||||||
}
|
|
||||||
printf("Local LAN ip address : %s\n", lanaddr);
|
|
||||||
#if 0
|
|
||||||
printf("getting \"%s\"\n", urls.ipcondescURL);
|
|
||||||
descXML = miniwget(urls.ipcondescURL, &descXMLsize);
|
|
||||||
if(descXML)
|
|
||||||
{
|
|
||||||
/*fwrite(descXML, 1, descXMLsize, stdout);*/
|
|
||||||
free(descXML); descXML = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(command)
|
|
||||||
{
|
|
||||||
case 'l':
|
|
||||||
DisplayInfos(&urls, &data);
|
|
||||||
ListRedirections(&urls, &data);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
SetRedirectAndTest(&urls, &data,
|
|
||||||
commandargv[0], commandargv[1],
|
|
||||||
commandargv[2], commandargv[3]);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
for(i=0; i<commandargc; i+=2)
|
|
||||||
{
|
|
||||||
RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
GetConnectionStatus(&urls, &data);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
for(i=0; i<commandargc; i+=2)
|
|
||||||
{
|
|
||||||
/*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
|
|
||||||
SetRedirectAndTest(&urls, &data,
|
|
||||||
lanaddr, commandargv[i],
|
|
||||||
commandargv[i], commandargv[i+1]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unknown switch -%c\n", command);
|
|
||||||
retcode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeUPNPUrls(&urls);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
|
|
||||||
retcode = 1;
|
|
||||||
}
|
|
||||||
freeUPNPDevlist(devlist); devlist = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "No IGD UPnP Device found on the network !\n");
|
|
||||||
retcode = 1;
|
|
||||||
}
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,611 +0,0 @@
|
|||||||
/* $Id: upnpcommands.c,v 1.26 2010/06/09 10:59:09 nanard Exp $ */
|
|
||||||
/* Project : miniupnp
|
|
||||||
* Author : Thomas Bernard
|
|
||||||
* Copyright (c) 2005-2010 Thomas Bernard
|
|
||||||
* This software is subject to the conditions detailed in the
|
|
||||||
* LICENCE file provided in this distribution.
|
|
||||||
* */
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "upnpcommands.h"
|
|
||||||
#include "miniupnpc.h"
|
|
||||||
|
|
||||||
static UNSIGNED_INTEGER
|
|
||||||
my_atoui(const char * s)
|
|
||||||
{
|
|
||||||
return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* */
|
|
||||||
LIBSPEC UNSIGNED_INTEGER
|
|
||||||
UPNP_GetTotalBytesSent(const char * controlURL,
|
|
||||||
const char * servicetype)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
unsigned int r = 0;
|
|
||||||
char * p;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
|
|
||||||
r = my_atoui(p);
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* */
|
|
||||||
LIBSPEC UNSIGNED_INTEGER
|
|
||||||
UPNP_GetTotalBytesReceived(const char * controlURL,
|
|
||||||
const char * servicetype)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
unsigned int r = 0;
|
|
||||||
char * p;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
|
|
||||||
r = my_atoui(p);
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* */
|
|
||||||
LIBSPEC UNSIGNED_INTEGER
|
|
||||||
UPNP_GetTotalPacketsSent(const char * controlURL,
|
|
||||||
const char * servicetype)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
unsigned int r = 0;
|
|
||||||
char * p;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
|
|
||||||
r = my_atoui(p);
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* */
|
|
||||||
LIBSPEC UNSIGNED_INTEGER
|
|
||||||
UPNP_GetTotalPacketsReceived(const char * controlURL,
|
|
||||||
const char * servicetype)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
unsigned int r = 0;
|
|
||||||
char * p;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
|
|
||||||
r = my_atoui(p);
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UPNP_GetStatusInfo() call the corresponding UPNP method
|
|
||||||
* returns the current status and uptime */
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_GetStatusInfo(const char * controlURL,
|
|
||||||
const char * servicetype,
|
|
||||||
char * status,
|
|
||||||
unsigned int * uptime,
|
|
||||||
char * lastconnerror)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
char * p;
|
|
||||||
char * up;
|
|
||||||
char * err;
|
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
|
|
||||||
if(!status && !uptime)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
up = GetValueFromNameValueList(&pdata, "NewUptime");
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
|
|
||||||
err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
|
|
||||||
if(p && up)
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
|
|
||||||
if(status) {
|
|
||||||
if(p){
|
|
||||||
strncpy(status, p, 64 );
|
|
||||||
status[63] = '\0';
|
|
||||||
}else
|
|
||||||
status[0]= '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(uptime) {
|
|
||||||
if(up)
|
|
||||||
sscanf(up,"%u",uptime);
|
|
||||||
else
|
|
||||||
uptime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lastconnerror) {
|
|
||||||
if(err) {
|
|
||||||
strncpy(lastconnerror, err, 64 );
|
|
||||||
lastconnerror[63] = '\0';
|
|
||||||
} else
|
|
||||||
lastconnerror[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &ret);
|
|
||||||
}
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
|
|
||||||
* returns the connection type */
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_GetConnectionTypeInfo(const char * controlURL,
|
|
||||||
const char * servicetype,
|
|
||||||
char * connectionType)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
char * p;
|
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
|
|
||||||
if(!connectionType)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
|
||||||
"GetConnectionTypeInfo", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewConnectionType");
|
|
||||||
/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
|
|
||||||
/* PossibleConnectionTypes will have several values.... */
|
|
||||||
if(p) {
|
|
||||||
strncpy(connectionType, p, 64 );
|
|
||||||
connectionType[63] = '\0';
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
} else
|
|
||||||
connectionType[0] = '\0';
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &ret);
|
|
||||||
}
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
|
|
||||||
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
|
|
||||||
* One of the values can be null
|
|
||||||
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
|
|
||||||
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
|
|
||||||
const char * servicetype,
|
|
||||||
unsigned int * bitrateDown,
|
|
||||||
unsigned int* bitrateUp)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
char * down;
|
|
||||||
char * up;
|
|
||||||
char * p;
|
|
||||||
|
|
||||||
if(!bitrateDown && !bitrateUp)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
/* shouldn't we use GetCommonLinkProperties ? */
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
|
||||||
"GetCommonLinkProperties", 0, buffer, &bufsize) < 0) {
|
|
||||||
/*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
|
|
||||||
/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
|
|
||||||
down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
|
|
||||||
up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
|
|
||||||
/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
|
|
||||||
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
|
|
||||||
if(down && up)
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
|
|
||||||
if(bitrateDown) {
|
|
||||||
if(down)
|
|
||||||
sscanf(down,"%u",bitrateDown);
|
|
||||||
else
|
|
||||||
*bitrateDown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bitrateUp) {
|
|
||||||
if(up)
|
|
||||||
sscanf(up,"%u",bitrateUp);
|
|
||||||
else
|
|
||||||
*bitrateUp = 0;
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &ret);
|
|
||||||
}
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*
|
|
||||||
* 402 Invalid Args - See UPnP Device Architecture section on Control.
|
|
||||||
* 501 Action Failed - See UPnP Device Architecture section on Control.
|
|
||||||
*/
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_GetExternalIPAddress(const char * controlURL,
|
|
||||||
const char * servicetype,
|
|
||||||
char * extIpAdd)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
char * p;
|
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
|
|
||||||
if(!extIpAdd || !controlURL || !servicetype)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
|
|
||||||
if(p) {
|
|
||||||
strncpy(extIpAdd, p, 16 );
|
|
||||||
extIpAdd[15] = '\0';
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
} else
|
|
||||||
extIpAdd[0] = '\0';
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
struct UPNParg * AddPortMappingArgs;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
const char * resVal;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if(!inPort || !inClient || !proto || !extPort)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
|
|
||||||
AddPortMappingArgs[0].elt = "NewRemoteHost";
|
|
||||||
AddPortMappingArgs[0].val = remoteHost;
|
|
||||||
AddPortMappingArgs[1].elt = "NewExternalPort";
|
|
||||||
AddPortMappingArgs[1].val = extPort;
|
|
||||||
AddPortMappingArgs[2].elt = "NewProtocol";
|
|
||||||
AddPortMappingArgs[2].val = proto;
|
|
||||||
AddPortMappingArgs[3].elt = "NewInternalPort";
|
|
||||||
AddPortMappingArgs[3].val = inPort;
|
|
||||||
AddPortMappingArgs[4].elt = "NewInternalClient";
|
|
||||||
AddPortMappingArgs[4].val = inClient;
|
|
||||||
AddPortMappingArgs[5].elt = "NewEnabled";
|
|
||||||
AddPortMappingArgs[5].val = "1";
|
|
||||||
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
|
|
||||||
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
|
|
||||||
AddPortMappingArgs[7].elt = "NewLeaseDuration";
|
|
||||||
AddPortMappingArgs[7].val = "0";
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize) < 0) {
|
|
||||||
free(AddPortMappingArgs);
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
/*buffer[bufsize] = '\0';*/
|
|
||||||
/*puts(buffer);*/
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(resVal) {
|
|
||||||
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(resVal, "%d", &ret);
|
|
||||||
} else {
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
}
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
free(AddPortMappingArgs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
|
||||||
const char * extPort, const char * proto,
|
|
||||||
const char * remoteHost)
|
|
||||||
{
|
|
||||||
/*struct NameValueParserData pdata;*/
|
|
||||||
struct UPNParg * DeletePortMappingArgs;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
const char * resVal;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if(!extPort || !proto)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
|
||||||
DeletePortMappingArgs[0].elt = "NewRemoteHost";
|
|
||||||
DeletePortMappingArgs[0].val = remoteHost;
|
|
||||||
DeletePortMappingArgs[1].elt = "NewExternalPort";
|
|
||||||
DeletePortMappingArgs[1].val = extPort;
|
|
||||||
DeletePortMappingArgs[2].elt = "NewProtocol";
|
|
||||||
DeletePortMappingArgs[2].val = proto;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
|
||||||
"DeletePortMapping",
|
|
||||||
DeletePortMappingArgs, buffer, &bufsize) < 0 ) {
|
|
||||||
free(DeletePortMappingArgs);
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(resVal) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(resVal, "%d", &ret);
|
|
||||||
} else {
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
}
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
free(DeletePortMappingArgs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
struct UPNParg * GetPortMappingArgs;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
char * p;
|
|
||||||
int r = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
if(!index)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
intClient[0] = '\0';
|
|
||||||
intPort[0] = '\0';
|
|
||||||
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
|
|
||||||
GetPortMappingArgs[0].elt = "NewPortMappingIndex";
|
|
||||||
GetPortMappingArgs[0].val = index;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
|
||||||
"GetGenericPortMappingEntry",
|
|
||||||
GetPortMappingArgs, buffer, &bufsize) < 0) {
|
|
||||||
free(GetPortMappingArgs);
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
|
|
||||||
if(p && rHost)
|
|
||||||
{
|
|
||||||
strncpy(rHost, p, 64);
|
|
||||||
rHost[63] = '\0';
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewExternalPort");
|
|
||||||
if(p && extPort)
|
|
||||||
{
|
|
||||||
strncpy(extPort, p, 6);
|
|
||||||
extPort[5] = '\0';
|
|
||||||
r = UPNPCOMMAND_SUCCESS;
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewProtocol");
|
|
||||||
if(p && protocol)
|
|
||||||
{
|
|
||||||
strncpy(protocol, p, 4);
|
|
||||||
protocol[3] = '\0';
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
|
||||||
if(p && intClient)
|
|
||||||
{
|
|
||||||
strncpy(intClient, p, 16);
|
|
||||||
intClient[15] = '\0';
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
|
|
||||||
if(p && intPort)
|
|
||||||
{
|
|
||||||
strncpy(intPort, p, 6);
|
|
||||||
intPort[5] = '\0';
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewEnabled");
|
|
||||||
if(p && enabled)
|
|
||||||
{
|
|
||||||
strncpy(enabled, p, 4);
|
|
||||||
enabled[3] = '\0';
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
|
|
||||||
if(p && desc)
|
|
||||||
{
|
|
||||||
strncpy(desc, p, 80);
|
|
||||||
desc[79] = '\0';
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
|
|
||||||
if(p && duration)
|
|
||||||
{
|
|
||||||
strncpy(duration, p, 16);
|
|
||||||
duration[15] = '\0';
|
|
||||||
}
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
r = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &r);
|
|
||||||
}
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
free(GetPortMappingArgs);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
|
|
||||||
const char * servicetype,
|
|
||||||
unsigned int * numEntries)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
char* p;
|
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize) < 0) {
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
DisplayNameValueList(buffer, bufsize);
|
|
||||||
#endif
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
|
|
||||||
if(numEntries && p) {
|
|
||||||
*numEntries = 0;
|
|
||||||
sscanf(p, "%u", numEntries);
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
|
|
||||||
* the result is returned in the intClient and intPort strings
|
|
||||||
* please provide 16 and 6 bytes of data */
|
|
||||||
LIBSPEC int
|
|
||||||
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
|
||||||
const char * servicetype,
|
|
||||||
const char * extPort,
|
|
||||||
const char * proto,
|
|
||||||
char * intClient,
|
|
||||||
char * intPort)
|
|
||||||
{
|
|
||||||
struct NameValueParserData pdata;
|
|
||||||
struct UPNParg * GetPortMappingArgs;
|
|
||||||
char buffer[4096];
|
|
||||||
int bufsize = 4096;
|
|
||||||
char * p;
|
|
||||||
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
|
|
||||||
if(!intPort || !intClient || !extPort || !proto)
|
|
||||||
return UPNPCOMMAND_INVALID_ARGS;
|
|
||||||
|
|
||||||
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
|
||||||
GetPortMappingArgs[0].elt = "NewRemoteHost";
|
|
||||||
GetPortMappingArgs[1].elt = "NewExternalPort";
|
|
||||||
GetPortMappingArgs[1].val = extPort;
|
|
||||||
GetPortMappingArgs[2].elt = "NewProtocol";
|
|
||||||
GetPortMappingArgs[2].val = proto;
|
|
||||||
if(simpleUPnPcommand(-1, controlURL, servicetype,
|
|
||||||
"GetSpecificPortMappingEntry",
|
|
||||||
GetPortMappingArgs, buffer, &bufsize) < 0) {
|
|
||||||
free(GetPortMappingArgs);
|
|
||||||
return UPNPCOMMAND_HTTP_ERROR;
|
|
||||||
}
|
|
||||||
/*DisplayNameValueList(buffer, bufsize);*/
|
|
||||||
ParseNameValue(buffer, bufsize, &pdata);
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
|
||||||
if(p) {
|
|
||||||
strncpy(intClient, p, 16);
|
|
||||||
intClient[15] = '\0';
|
|
||||||
ret = UPNPCOMMAND_SUCCESS;
|
|
||||||
} else
|
|
||||||
intClient[0] = '\0';
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
|
|
||||||
if(p) {
|
|
||||||
strncpy(intPort, p, 6);
|
|
||||||
intPort[5] = '\0';
|
|
||||||
} else
|
|
||||||
intPort[0] = '\0';
|
|
||||||
|
|
||||||
p = GetValueFromNameValueList(&pdata, "errorCode");
|
|
||||||
if(p) {
|
|
||||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
|
||||||
sscanf(p, "%d", &ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearNameValueList(&pdata);
|
|
||||||
free(GetPortMappingArgs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
172
thirdparty/libportfwd/third-party/miniupnpc-1.6/CMakeLists.txt
vendored
Normal file
172
thirdparty/libportfwd/third-party/miniupnpc-1.6/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
cmake_minimum_required (VERSION 2.6)
|
||||||
|
|
||||||
|
project (miniupnpc C)
|
||||||
|
set (MINIUPNPC_VERSION 1.5)
|
||||||
|
set (MINIUPNPC_API_VERSION 8)
|
||||||
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
|
if (WIN32)
|
||||||
|
set (DEFAULT_BUILD_TYPE MinSizeRel)
|
||||||
|
else (WIN32)
|
||||||
|
set (DEFAULT_BUILD_TYPE RelWithDebInfo)
|
||||||
|
endif(WIN32)
|
||||||
|
set (CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING
|
||||||
|
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
||||||
|
FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
|
||||||
|
option (UPNPC_BUILD_SHARED "Build shared library" TRUE)
|
||||||
|
if (NOT WIN32)
|
||||||
|
option (UPNPC_BUILD_TESTS "Build test executables" TRUE)
|
||||||
|
endif (NOT WIN32)
|
||||||
|
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
|
||||||
|
|
||||||
|
mark_as_advanced (NO_GETADDRINFO)
|
||||||
|
|
||||||
|
if (NO_GETADDRINFO)
|
||||||
|
add_definitions (-DNO_GETADDRINFO)
|
||||||
|
endif (NO_GETADDRINFO)
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
|
||||||
|
else (NOT WIN32)
|
||||||
|
add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends
|
||||||
|
endif (NOT WIN32)
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
|
add_definitions (-DMACOSX -D_DARWIN_C_SOURCE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Set compiler specific build flags
|
||||||
|
if (CMAKE_COMPILER_IS_GNUC)
|
||||||
|
# Set our own default flags at first run.
|
||||||
|
if (NOT CONFIGURED)
|
||||||
|
|
||||||
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
|
||||||
|
set (_PIC -fPIC)
|
||||||
|
endif (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
|
||||||
|
|
||||||
|
set (CMAKE_C_FLAGS "${_PIC} -Wall $ENV{CFLAGS}" # CMAKE_C_FLAGS gets appended to the other C flags
|
||||||
|
CACHE STRING "Flags used by the C compiler during normal builds." FORCE)
|
||||||
|
set (CMAKE_C_FLAGS_DEBUG "-g -DDDEBUG"
|
||||||
|
CACHE STRING "Flags used by the C compiler during debug builds." FORCE)
|
||||||
|
set (CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG"
|
||||||
|
CACHE STRING "Flags used by the C compiler during release builds." FORCE)
|
||||||
|
set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG"
|
||||||
|
CACHE STRING "Flags used by the C compiler during release builds." FORCE)
|
||||||
|
set (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG"
|
||||||
|
CACHE STRING "Flags used by the C compiler during release builds." FORCE)
|
||||||
|
|
||||||
|
endif (NOT CONFIGURED)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
configure_file (${CMAKE_SOURCE_DIR}/miniupnpcstrings.h.cmake ${CMAKE_BINARY_DIR}/miniupnpcstrings.h)
|
||||||
|
include_directories (${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
set (MINIUPNPC_SOURCES
|
||||||
|
igd_desc_parse.c
|
||||||
|
miniupnpc.c
|
||||||
|
minixml.c
|
||||||
|
minisoap.c
|
||||||
|
miniwget.c
|
||||||
|
upnpc.c
|
||||||
|
upnpcommands.c
|
||||||
|
upnpreplyparse.c
|
||||||
|
upnperrors.c
|
||||||
|
connecthostport.c
|
||||||
|
portlistingparse.c
|
||||||
|
)
|
||||||
|
|
||||||
|
if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
|
||||||
|
set (MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c)
|
||||||
|
endif (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set_source_files_properties (${MINIUPNPC_SOURCES} PROPERTIES
|
||||||
|
COMPILE_DEFINITIONS STATICLIB
|
||||||
|
COMPILE_DEFINITIONS MINIUPNP_EXPORTS
|
||||||
|
)
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
find_library (WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32)
|
||||||
|
find_library (IPHLPAPI_LIBRARY NAMES iphlpapi)
|
||||||
|
set (LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS})
|
||||||
|
#elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris")
|
||||||
|
# find_library (SOCKET_LIBRARY NAMES socket)
|
||||||
|
# find_library (NSL_LIBRARY NAMES nsl)
|
||||||
|
# find_library (RESOLV_LIBRARY NAMES resolv)
|
||||||
|
# set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS})
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
if (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
|
||||||
|
message (FATAL "Both shared and static libraries are disabled!")
|
||||||
|
endif (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
|
||||||
|
|
||||||
|
if (UPNPC_BUILD_STATIC)
|
||||||
|
add_library (upnpc-static STATIC ${MINIUPNPC_SOURCES})
|
||||||
|
set_target_properties (upnpc-static PROPERTIES OUTPUT_NAME "miniupnpc")
|
||||||
|
target_link_libraries (upnpc-static ${LDLIBS})
|
||||||
|
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-static)
|
||||||
|
set (UPNPC_LIBRARY_TARGET upnpc-static)
|
||||||
|
endif (UPNPC_BUILD_STATIC)
|
||||||
|
|
||||||
|
if (UPNPC_BUILD_SHARED)
|
||||||
|
add_library (upnpc-shared SHARED ${MINIUPNPC_SOURCES})
|
||||||
|
set_target_properties (upnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc")
|
||||||
|
set_target_properties (upnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION})
|
||||||
|
set_target_properties (upnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION})
|
||||||
|
target_link_libraries (upnpc-shared ${LDLIBS})
|
||||||
|
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-shared)
|
||||||
|
set (UPNPC_LIBRARY_TARGET upnpc-shared)
|
||||||
|
endif (UPNPC_BUILD_SHARED)
|
||||||
|
|
||||||
|
if (UPNPC_BUILD_TESTS)
|
||||||
|
add_executable (testminixml testminixml.c minixml.c igd_desc_parse.c)
|
||||||
|
target_link_libraries (testminixml ${LDLIBS})
|
||||||
|
|
||||||
|
add_executable (minixmlvalid minixmlvalid.c minixml.c)
|
||||||
|
target_link_libraries (minixmlvalid ${LDLIBS})
|
||||||
|
|
||||||
|
add_executable (testupnpreplyparse testupnpreplyparse.c
|
||||||
|
minixml.c upnpreplyparse.c)
|
||||||
|
target_link_libraries (testupnpreplyparse ${LDLIBS})
|
||||||
|
|
||||||
|
add_executable (testigddescparse testigddescparse.c
|
||||||
|
igd_desc_parse.c minixml.c miniupnpc.c miniwget.c minissdpc.c
|
||||||
|
upnpcommands.c upnpreplyparse.c minisoap.c connecthostport.c
|
||||||
|
portlistingparse.c
|
||||||
|
)
|
||||||
|
target_link_libraries (testigddescparse ${LDLIBS})
|
||||||
|
|
||||||
|
add_executable (testminiwget testminiwget.c
|
||||||
|
miniwget.c miniupnpc.c minisoap.c upnpcommands.c minissdpc.c
|
||||||
|
upnpreplyparse.c minixml.c igd_desc_parse.c connecthostport.c
|
||||||
|
portlistingparse.c
|
||||||
|
)
|
||||||
|
target_link_libraries (testminiwget ${LDLIBS})
|
||||||
|
|
||||||
|
# set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} testminixml minixmlvalid testupnpreplyparse testigddescparse testminiwget)
|
||||||
|
endif (UPNPC_BUILD_TESTS)
|
||||||
|
|
||||||
|
|
||||||
|
install (TARGETS ${UPNPC_INSTALL_TARGETS}
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||||
|
ARCHIVE DESTINATION lib${LIB_SUFFIX}
|
||||||
|
)
|
||||||
|
install (FILES
|
||||||
|
miniupnpc.h
|
||||||
|
miniwget.h
|
||||||
|
upnpcommands.h
|
||||||
|
igd_desc_parse.h
|
||||||
|
upnpreplyparse.h
|
||||||
|
upnperrors.h
|
||||||
|
declspec.h
|
||||||
|
DESTINATION include/miniupnpc
|
||||||
|
)
|
||||||
|
|
||||||
|
set (CONFIGURED YES CACHE INTERNAL "")
|
||||||
|
|
||||||
|
# vim: ts=2:sw=2
|
@@ -1,6 +1,108 @@
|
|||||||
$Id: Changelog.txt,v 1.117 2010/06/09 10:59:08 nanard Exp $
|
$Id: Changelog.txt,v 1.152 2011/07/25 18:02:11 nanard Exp $
|
||||||
miniUPnP client Changelog.
|
miniUPnP client Changelog.
|
||||||
|
|
||||||
|
VERSION 1.6 : released 2011/07/25
|
||||||
|
|
||||||
|
2011/07/25:
|
||||||
|
Update doc for version 1.6 release
|
||||||
|
|
||||||
|
2011/06/18:
|
||||||
|
Fix for windows in miniwget.c
|
||||||
|
|
||||||
|
2011/06/04:
|
||||||
|
display remote host in port mapping listing
|
||||||
|
|
||||||
|
2011/06/03:
|
||||||
|
Fix in make install : there were missing headers
|
||||||
|
|
||||||
|
2011/05/26:
|
||||||
|
Fix the socket leak in miniwget thanks to Richard Marsh.
|
||||||
|
Permit to add leaseduration in -a command. Display lease duration.
|
||||||
|
|
||||||
|
2011/05/15:
|
||||||
|
Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
|
||||||
|
|
||||||
|
2011/05/09:
|
||||||
|
add a test in testminiwget.sh.
|
||||||
|
more error checking in miniwget.c
|
||||||
|
|
||||||
|
2011/05/06:
|
||||||
|
Adding some tool to test and validate miniwget.c
|
||||||
|
simplified and debugged miniwget.c
|
||||||
|
|
||||||
|
2011/04/11:
|
||||||
|
moving ReceiveData() to a receivedata.c file.
|
||||||
|
parsing presentation url
|
||||||
|
adding IGD v2 WANIPv6FirewallControl commands
|
||||||
|
|
||||||
|
2011/04/10:
|
||||||
|
update of miniupnpcmodule.c
|
||||||
|
comments in miniwget.c, update in testminiwget
|
||||||
|
Adding errors codes from IGD v2
|
||||||
|
new functions in upnpc.c for IGD v2
|
||||||
|
|
||||||
|
2011/04/09:
|
||||||
|
Support for litteral ip v6 address in miniwget
|
||||||
|
|
||||||
|
2011/04/08:
|
||||||
|
Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
|
||||||
|
Updating APIVERSION
|
||||||
|
Supporting IPV6 in upnpDiscover()
|
||||||
|
Adding a -6 option to upnpc command line tool
|
||||||
|
|
||||||
|
2011/03/18:
|
||||||
|
miniwget/parseURL() : return an error when url param is null.
|
||||||
|
fixing GetListOfPortMappings()
|
||||||
|
|
||||||
|
2011/03/14:
|
||||||
|
upnpDiscover() now reporting an error code.
|
||||||
|
improvements in comments.
|
||||||
|
|
||||||
|
2011/03/11:
|
||||||
|
adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
|
||||||
|
|
||||||
|
2011/02/15:
|
||||||
|
Implementation of GetListOfPortMappings()
|
||||||
|
|
||||||
|
2011/02/07:
|
||||||
|
updates to minixml to support character data starting with spaces
|
||||||
|
minixml now support CDATA
|
||||||
|
upnpreplyparse treats <NewPortListing> specificaly
|
||||||
|
change in simpleUPnPcommand to return the buffer (simplification)
|
||||||
|
|
||||||
|
2011/02/06:
|
||||||
|
Added leaseDuration argument to AddPortMapping()
|
||||||
|
Starting to implement GetListOfPortMappings()
|
||||||
|
|
||||||
|
2011/01/11:
|
||||||
|
updating wingenminiupnpcstrings.c
|
||||||
|
|
||||||
|
2011/01/04:
|
||||||
|
improving updateminiupnpcstrings.sh
|
||||||
|
|
||||||
|
VERSION 1.5 : released 2011/01/01
|
||||||
|
|
||||||
|
2010/12/21:
|
||||||
|
use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
|
||||||
|
|
||||||
|
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:
|
2010/06/09:
|
||||||
update to python module to match modification made on 2010/04/05
|
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
|
update to Java test code to match modification made on 2010/04/05
|
@@ -1,4 +1,5 @@
|
|||||||
Copyright (c) 2005-2009, Thomas BERNARD
|
MiniUPnPc
|
||||||
|
Copyright (c) 2005-2011, Thomas BERNARD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
5
thirdparty/libportfwd/third-party/miniupnpc-1.6/MANIFEST.in
vendored
Normal file
5
thirdparty/libportfwd/third-party/miniupnpc-1.6/MANIFEST.in
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
include README
|
||||||
|
include miniupnpcmodule.c
|
||||||
|
include setup.py
|
||||||
|
include *.h
|
||||||
|
include libminiupnpc.a
|
@@ -1,7 +1,7 @@
|
|||||||
Project: miniupnp
|
Project: miniupnp
|
||||||
Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
Author: Thomas Bernard
|
Author: Thomas Bernard
|
||||||
Copyright (c) 2005-2009 Thomas Bernard
|
Copyright (c) 2005-2011 Thomas Bernard
|
||||||
This software is subject to the conditions detailed in the
|
This software is subject to the conditions detailed in the
|
||||||
LICENSE file provided within this distribution.
|
LICENSE file provided within this distribution.
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ Under win32, to compile with MinGW, type "mingw32make.bat".
|
|||||||
The compilation is known to work under linux, FreeBSD,
|
The compilation is known to work under linux, FreeBSD,
|
||||||
OpenBSD, MacOS X, AmigaOS and cygwin.
|
OpenBSD, MacOS X, AmigaOS and cygwin.
|
||||||
The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
|
The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
|
||||||
|
upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
|
||||||
|
|
||||||
To install the library and headers on the system use :
|
To install the library and headers on the system use :
|
||||||
> su
|
> su
|
||||||
@@ -53,4 +54,6 @@ e-mail : miniupnp@free.fr
|
|||||||
If you are using libminiupnpc in your application, please
|
If you are using libminiupnpc in your application, please
|
||||||
send me an email !
|
send me an email !
|
||||||
|
|
||||||
|
For any question, you can use the web forum :
|
||||||
|
http://miniupnp.tuxfamily.org/forum/
|
||||||
|
|
1
thirdparty/libportfwd/third-party/miniupnpc-1.6/VERSION
vendored
Normal file
1
thirdparty/libportfwd/third-party/miniupnpc-1.6/VERSION
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1.6
|
@@ -1,13 +1,15 @@
|
|||||||
/* $Id: connecthostport.c,v 1.2 2010/04/05 00:08:15 nanard Exp $ */
|
/* $Id: connecthostport.c,v 1.5 2011/04/09 08:49:50 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2010 Thomas Bernard
|
* Copyright (c) 2010-2011 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided in this distribution. */
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
/* use getaddrinfo() or gethostbyname()
|
/* use getaddrinfo() or gethostbyname()
|
||||||
* uncomment the following line in order to use gethostbyname() */
|
* uncomment the following line in order to use gethostbyname() */
|
||||||
/* #define USE_GETHOSTBYNAME */
|
#ifdef NO_GETADDRINFO
|
||||||
|
#define USE_GETHOSTBYNAME
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -15,11 +17,13 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define herror
|
#define herror
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
#else /* #ifdef WIN32 */
|
#else /* #ifdef WIN32 */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -55,6 +59,7 @@ int connecthostport(const char * host, unsigned short port)
|
|||||||
struct sockaddr_in dest;
|
struct sockaddr_in dest;
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
#else /* #ifdef USE_GETHOSTBYNAME */
|
#else /* #ifdef USE_GETHOSTBYNAME */
|
||||||
|
char tmp_host[MAXHOSTNAMELEN+1];
|
||||||
char port_str[8];
|
char port_str[8];
|
||||||
struct addrinfo *ai, *p;
|
struct addrinfo *ai, *p;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
@@ -137,7 +142,22 @@ int connecthostport(const char * host, unsigned short port)
|
|||||||
hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
|
hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
|
||||||
/* hints.ai_protocol = IPPROTO_TCP; */
|
/* hints.ai_protocol = IPPROTO_TCP; */
|
||||||
snprintf(port_str, sizeof(port_str), "%hu", port);
|
snprintf(port_str, sizeof(port_str), "%hu", port);
|
||||||
n = getaddrinfo(host, port_str, &hints, &ai);
|
if(host[0] == '[')
|
||||||
|
{
|
||||||
|
/* literal ip v6 address */
|
||||||
|
int i;
|
||||||
|
for(i = 0; host[i+1] && (host[i+1] != ']') && i < MAXHOSTNAMELEN; i++)
|
||||||
|
{
|
||||||
|
tmp_host[i] = host[i+1];
|
||||||
|
}
|
||||||
|
tmp_host[i] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(tmp_host, host, MAXHOSTNAMELEN);
|
||||||
|
}
|
||||||
|
tmp_host[MAXHOSTNAMELEN] = '\0';
|
||||||
|
n = getaddrinfo(tmp_host, port_str, &hints, &ai);
|
||||||
if(n != 0)
|
if(n != 0)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: igd_desc_parse.c,v 1.10 2010/04/05 20:36:59 nanard Exp $ */
|
/* $Id: igd_desc_parse.c,v 1.14 2011/04/11 09:19:24 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
@@ -46,6 +46,9 @@ void IGDendelt(void * d, const char * name, int l)
|
|||||||
if(0==strcmp(datas->tmp.servicetype,
|
if(0==strcmp(datas->tmp.servicetype,
|
||||||
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
|
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
|
||||||
memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
|
memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
|
||||||
|
} else if(0==strcmp(datas->tmp.servicetype,
|
||||||
|
"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1")) {
|
||||||
|
memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
|
||||||
} else if(0==strcmp(datas->tmp.servicetype,
|
} else if(0==strcmp(datas->tmp.servicetype,
|
||||||
"urn:schemas-upnp-org:service:WANIPConnection:1")
|
"urn:schemas-upnp-org:service:WANIPConnection:1")
|
||||||
|| 0==strcmp(datas->tmp.servicetype,
|
|| 0==strcmp(datas->tmp.servicetype,
|
||||||
@@ -69,6 +72,8 @@ void IGDdata(void * d, const char * data, int l)
|
|||||||
datas->level, datas->cureltname, l, data); */
|
datas->level, datas->cureltname, l, data); */
|
||||||
if( !strcmp(datas->cureltname, "URLBase") )
|
if( !strcmp(datas->cureltname, "URLBase") )
|
||||||
dstmember = datas->urlbase;
|
dstmember = datas->urlbase;
|
||||||
|
else if( !strcmp(datas->cureltname, "presentationURL") )
|
||||||
|
dstmember = datas->presentationurl;
|
||||||
else if( !strcmp(datas->cureltname, "serviceType") )
|
else if( !strcmp(datas->cureltname, "serviceType") )
|
||||||
dstmember = datas->tmp.servicetype;
|
dstmember = datas->tmp.servicetype;
|
||||||
else if( !strcmp(datas->cureltname, "controlURL") )
|
else if( !strcmp(datas->cureltname, "controlURL") )
|
||||||
@@ -97,7 +102,7 @@ void printIGD(struct IGDdatas * d)
|
|||||||
printf(" controlURL = '%s'\n", d->CIF.controlurl);
|
printf(" controlURL = '%s'\n", d->CIF.controlurl);
|
||||||
printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
|
printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
|
||||||
printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
|
printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
|
||||||
printf("WAN Connection Device (IP or PPP Connection):\n");
|
printf("primary WAN Connection Device (IP or PPP Connection):\n");
|
||||||
/*printf(" deviceType = '%s'\n", d->first.devicetype);*/
|
/*printf(" deviceType = '%s'\n", d->first.devicetype);*/
|
||||||
printf(" servicetype = '%s'\n", d->first.servicetype);
|
printf(" servicetype = '%s'\n", d->first.servicetype);
|
||||||
printf(" controlURL = '%s'\n", d->first.controlurl);
|
printf(" controlURL = '%s'\n", d->first.controlurl);
|
||||||
@@ -109,6 +114,12 @@ void printIGD(struct IGDdatas * d)
|
|||||||
printf(" controlURL = '%s'\n", d->second.controlurl);
|
printf(" controlURL = '%s'\n", d->second.controlurl);
|
||||||
printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
|
printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
|
||||||
printf(" SCPDURL = '%s'\n", d->second.scpdurl);
|
printf(" SCPDURL = '%s'\n", d->second.scpdurl);
|
||||||
|
printf("WAN IPv6 Firewall Control :\n");
|
||||||
|
/*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
|
||||||
|
printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
|
||||||
|
printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
|
||||||
|
printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
|
||||||
|
printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: igd_desc_parse.h,v 1.7 2010/04/05 20:36:59 nanard Exp $ */
|
/* $Id: igd_desc_parse.h,v 1.10 2011/04/11 09:19:24 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
@@ -23,6 +23,7 @@ struct IGDdatas_service {
|
|||||||
struct IGDdatas {
|
struct IGDdatas {
|
||||||
char cureltname[MINIUPNPC_URL_MAXSIZE];
|
char cureltname[MINIUPNPC_URL_MAXSIZE];
|
||||||
char urlbase[MINIUPNPC_URL_MAXSIZE];
|
char urlbase[MINIUPNPC_URL_MAXSIZE];
|
||||||
|
char presentationurl[MINIUPNPC_URL_MAXSIZE];
|
||||||
int level;
|
int level;
|
||||||
/*int state;*/
|
/*int state;*/
|
||||||
/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
|
/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
|
||||||
@@ -32,6 +33,8 @@ struct IGDdatas {
|
|||||||
struct IGDdatas_service first;
|
struct IGDdatas_service first;
|
||||||
/* if both WANIPConnection and WANPPPConnection are present */
|
/* if both WANIPConnection and WANPPPConnection are present */
|
||||||
struct IGDdatas_service second;
|
struct IGDdatas_service second;
|
||||||
|
/* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
|
||||||
|
struct IGDdatas_service IPv6FC;
|
||||||
/* tmp */
|
/* tmp */
|
||||||
struct IGDdatas_service tmp;
|
struct IGDdatas_service tmp;
|
||||||
};
|
};
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: minisoap.c,v 1.19 2010/04/12 20:39:41 nanard Exp $ */
|
/* $Id: minisoap.c,v 1.21 2011/03/22 19:15:35 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005-2009 Thomas Bernard
|
* Copyright (c) 2005-2009 Thomas Bernard
|
||||||
@@ -106,9 +106,14 @@ int soapPostSubmit(int fd,
|
|||||||
"\r\n",
|
"\r\n",
|
||||||
url, httpversion, host, portstr, bodysize, action);
|
url, httpversion, host, portstr, bodysize, action);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("SOAP request : headersize=%d bodysize=%d\n",
|
/*printf("SOAP request : headersize=%d bodysize=%d\n",
|
||||||
headerssize, bodysize);
|
headerssize, bodysize);
|
||||||
/*printf("%s", headerbuf);*/
|
*/
|
||||||
|
printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
|
||||||
|
url, httpversion, host, portstr);
|
||||||
|
printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
|
||||||
|
printf("Headers :\n%s", headerbuf);
|
||||||
|
printf("Body :\n%s\n", body);
|
||||||
#endif
|
#endif
|
||||||
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
|
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
|
||||||
}
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: minissdpc.c,v 1.13 2009/12/04 16:57:29 nanard Exp $ */
|
/* $Id: minissdpc.c,v 1.14 2010/11/25 09:57:25 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
* copyright (c) 2005-2009 Thomas Bernard
|
* copyright (c) 2005-2009 Thomas Bernard
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(__amigaos__) || defined(__amigaos4__)
|
#if defined(__amigaos__) || defined(__amigaos4__)
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -23,9 +25,7 @@
|
|||||||
#define uint16_t unsigned short
|
#define uint16_t unsigned short
|
||||||
#endif
|
#endif
|
||||||
/* Hack */
|
/* Hack */
|
||||||
#include <winsock.h>
|
|
||||||
#define UNIX_PATH_LEN 108
|
#define UNIX_PATH_LEN 108
|
||||||
#include <stdint.h>
|
|
||||||
struct sockaddr_un {
|
struct sockaddr_un {
|
||||||
uint16_t sun_family;
|
uint16_t sun_family;
|
||||||
char sun_path[UNIX_PATH_LEN];
|
char sun_path[UNIX_PATH_LEN];
|
@@ -1,7 +1,7 @@
|
|||||||
/* $Id: miniupnpc.c,v 1.81 2010/04/17 22:07:59 nanard Exp $ */
|
/* $Id: miniupnpc.c,v 1.95 2011/05/15 21:42:26 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
* copyright (c) 2005-2010 Thomas Bernard
|
* copyright (c) 2005-2011 Thomas Bernard
|
||||||
* This software is subjet to the conditions detailed in the
|
* This software is subjet to the conditions detailed in the
|
||||||
* provided LICENSE file. */
|
* provided LICENSE file. */
|
||||||
#define __EXTENSIONS__ 1
|
#define __EXTENSIONS__ 1
|
||||||
@@ -16,10 +16,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define _DARWIN_C_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -30,11 +26,13 @@
|
|||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
#ifndef strncasecmp
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
#define strncasecmp _memicmp
|
#define strncasecmp _memicmp
|
||||||
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
#define strncasecmp memicmp
|
#define strncasecmp memicmp
|
||||||
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
|
#endif /* #ifndef strncasecmp */
|
||||||
#define MAXHOSTNAMELEN 64
|
#define MAXHOSTNAMELEN 64
|
||||||
#else /* #ifdef WIN32 */
|
#else /* #ifdef WIN32 */
|
||||||
/* Standard POSIX includes */
|
/* Standard POSIX includes */
|
||||||
@@ -51,13 +49,13 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <net/if.h>
|
||||||
#if !defined(__amigaos__) && !defined(__amigaos4__)
|
#if !defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
#define MINIUPNPC_IGNORE_EINTR
|
|
||||||
#endif /* #else WIN32 */
|
#endif /* #else WIN32 */
|
||||||
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@@ -74,6 +72,7 @@
|
|||||||
#include "minixml.h"
|
#include "minixml.h"
|
||||||
#include "upnpcommands.h"
|
#include "upnpcommands.h"
|
||||||
#include "connecthostport.h"
|
#include "connecthostport.h"
|
||||||
|
#include "receivedata.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
||||||
@@ -103,83 +102,14 @@ LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * d
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* getcontentlenfromline() : parse the Content-Length HTTP header line.
|
|
||||||
* Content-length: nnn */
|
|
||||||
static int getcontentlenfromline(const char * p, int n)
|
|
||||||
{
|
|
||||||
static const char contlenstr[] = "content-length";
|
|
||||||
const char * p2 = contlenstr;
|
|
||||||
int a = 0;
|
|
||||||
while(*p2)
|
|
||||||
{
|
|
||||||
if(n==0)
|
|
||||||
return -1;
|
|
||||||
if(*p2 != *p && *p2 != (*p + 32))
|
|
||||||
return -1;
|
|
||||||
p++; p2++; n--;
|
|
||||||
}
|
|
||||||
if(n==0)
|
|
||||||
return -1;
|
|
||||||
if(*p != ':')
|
|
||||||
return -1;
|
|
||||||
p++; n--;
|
|
||||||
while(*p == ' ')
|
|
||||||
{
|
|
||||||
if(n==0)
|
|
||||||
return -1;
|
|
||||||
p++; n--;
|
|
||||||
}
|
|
||||||
while(*p >= '0' && *p <= '9')
|
|
||||||
{
|
|
||||||
if(n==0)
|
|
||||||
return -1;
|
|
||||||
a = (a * 10) + (*p - '0');
|
|
||||||
p++; n--;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* getContentLengthAndHeaderLength()
|
|
||||||
* retrieve header length and content length from an HTTP response
|
|
||||||
* TODO : retrieve Transfer-Encoding: header value, in order to support
|
|
||||||
* HTTP/1.1, chunked transfer encoding must be supported. */
|
|
||||||
static void
|
|
||||||
getContentLengthAndHeaderLength(char * p, int n,
|
|
||||||
int * contentlen, int * headerlen)
|
|
||||||
{
|
|
||||||
char * line;
|
|
||||||
int linelen;
|
|
||||||
int r;
|
|
||||||
line = p;
|
|
||||||
while(line < p + n)
|
|
||||||
{
|
|
||||||
linelen = 0;
|
|
||||||
while(line[linelen] != '\r' && line[linelen] != '\r')
|
|
||||||
{
|
|
||||||
if(line+linelen >= p+n)
|
|
||||||
return;
|
|
||||||
linelen++;
|
|
||||||
}
|
|
||||||
r = getcontentlenfromline(line, linelen);
|
|
||||||
if(r>0)
|
|
||||||
*contentlen = r;
|
|
||||||
line = line + linelen + 2;
|
|
||||||
if(line[0] == '\r' && line[1] == '\n')
|
|
||||||
{
|
|
||||||
*headerlen = (line - p) + 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* simpleUPnPcommand2 :
|
/* simpleUPnPcommand2 :
|
||||||
* not so simple !
|
* not so simple !
|
||||||
* return values :
|
* return values :
|
||||||
* 0 - OK
|
* pointer - OK
|
||||||
* -1 - error */
|
* NULL - error */
|
||||||
static int simpleUPnPcommand2(int s, const char * url, const char * service,
|
char * simpleUPnPcommand2(int s, const char * url, const char * service,
|
||||||
const char * action, struct UPNParg * args,
|
const char * action, struct UPNParg * args,
|
||||||
char * buffer, int * bufsize, const char * httpversion)
|
int * bufsize, const char * httpversion)
|
||||||
{
|
{
|
||||||
char hostname[MAXHOSTNAMELEN+1];
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
unsigned short port = 0;
|
unsigned short port = 0;
|
||||||
@@ -187,10 +117,9 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
|
|||||||
char soapact[128];
|
char soapact[128];
|
||||||
char soapbody[2048];
|
char soapbody[2048];
|
||||||
char * buf;
|
char * buf;
|
||||||
int buffree;
|
|
||||||
int n;
|
int n;
|
||||||
int contentlen, headerlen; /* for the response */
|
|
||||||
|
|
||||||
|
*bufsize = 0;
|
||||||
snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
|
snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
|
||||||
if(args==NULL)
|
if(args==NULL)
|
||||||
{
|
{
|
||||||
@@ -225,8 +154,7 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
|
|||||||
if(soapbody + sizeof(soapbody) <= p + 100)
|
if(soapbody + sizeof(soapbody) <= p + 100)
|
||||||
{
|
{
|
||||||
/* we keep a margin of at least 100 bytes */
|
/* we keep a margin of at least 100 bytes */
|
||||||
*bufsize = 0;
|
return NULL;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
*(p++) = '<';
|
*(p++) = '<';
|
||||||
pe = args->elt;
|
pe = args->elt;
|
||||||
@@ -256,14 +184,13 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
|
|||||||
strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
|
strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
|
||||||
soapbody + sizeof(soapbody) - p);
|
soapbody + sizeof(soapbody) - p);
|
||||||
}
|
}
|
||||||
if(!parseURL(url, hostname, &port, &path)) return -1;
|
if(!parseURL(url, hostname, &port, &path)) return NULL;
|
||||||
if(s<0)
|
if(s<0)
|
||||||
{
|
{
|
||||||
s = connecthostport(hostname, port);
|
s = connecthostport(hostname, port);
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
{
|
{
|
||||||
*bufsize = 0;
|
return NULL;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,55 +200,43 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
|
|||||||
printf("Error sending SOAP request\n");
|
printf("Error sending SOAP request\n");
|
||||||
#endif
|
#endif
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentlen = -1;
|
buf = getHTTPResponse(s, bufsize);
|
||||||
headerlen = -1;
|
|
||||||
buf = buffer;
|
|
||||||
buffree = *bufsize;
|
|
||||||
*bufsize = 0;
|
|
||||||
while ((n = ReceiveData(s, buf, buffree, 5000)) > 0) {
|
|
||||||
buffree -= n;
|
|
||||||
buf += n;
|
|
||||||
*bufsize += n;
|
|
||||||
getContentLengthAndHeaderLength(buffer, *bufsize,
|
|
||||||
&contentlen, &headerlen);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("received n=%dbytes bufsize=%d ContLen=%d HeadLen=%d\n",
|
if(*bufsize > 0 && buf)
|
||||||
n, *bufsize, contentlen, headerlen);
|
{
|
||||||
#endif
|
printf("SOAP Response :\n%.*s\n", *bufsize, buf);
|
||||||
/* break if we received everything */
|
|
||||||
if(contentlen > 0 && headerlen > 0 && *bufsize >= contentlen+headerlen)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
return 0;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* simpleUPnPcommand :
|
/* simpleUPnPcommand :
|
||||||
* not so simple !
|
* not so simple !
|
||||||
* return values :
|
* return values :
|
||||||
* 0 - OK
|
* pointer - OK
|
||||||
* -1 - error */
|
* NULL - error */
|
||||||
int simpleUPnPcommand(int s, const char * url, const char * service,
|
char * simpleUPnPcommand(int s, const char * url, const char * service,
|
||||||
const char * action, struct UPNParg * args,
|
const char * action, struct UPNParg * args,
|
||||||
char * buffer, int * bufsize)
|
int * bufsize)
|
||||||
{
|
{
|
||||||
int result;
|
char * buf;
|
||||||
int origbufsize = *bufsize;
|
|
||||||
|
|
||||||
result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0");
|
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
|
||||||
if (result < 0 || *bufsize == 0)
|
/*
|
||||||
|
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
|
||||||
|
if (!buf || *bufsize == 0)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
|
printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
|
||||||
#endif
|
#endif
|
||||||
*bufsize = origbufsize;
|
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
|
||||||
result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
|
|
||||||
}
|
}
|
||||||
return result;
|
*/
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parseMSEARCHReply()
|
/* parseMSEARCHReply()
|
||||||
@@ -337,7 +252,7 @@ parseMSEARCHReply(const char * reply, int size,
|
|||||||
int a, b, i;
|
int a, b, i;
|
||||||
i = 0;
|
i = 0;
|
||||||
a = i; /* start of the line */
|
a = i; /* start of the line */
|
||||||
b = 0;
|
b = 0; /* end of the "header" (position of the colon) */
|
||||||
while(i<size)
|
while(i<size)
|
||||||
{
|
{
|
||||||
switch(reply[i])
|
switch(reply[i])
|
||||||
@@ -362,6 +277,7 @@ parseMSEARCHReply(const char * reply, int size,
|
|||||||
putchar(reply[j]);
|
putchar(reply[j]);
|
||||||
}
|
}
|
||||||
putchar('\n');*/
|
putchar('\n');*/
|
||||||
|
/* skip the colon and white spaces */
|
||||||
do { b++; } while(reply[b]==' ');
|
do { b++; } while(reply[b]==' ');
|
||||||
if(0==strncasecmp(reply+a, "location", 8))
|
if(0==strncasecmp(reply+a, "location", 8))
|
||||||
{
|
{
|
||||||
@@ -389,26 +305,36 @@ parseMSEARCHReply(const char * reply, int size,
|
|||||||
#define XSTR(s) STR(s)
|
#define XSTR(s) STR(s)
|
||||||
#define STR(s) #s
|
#define STR(s) #s
|
||||||
#define UPNP_MCAST_ADDR "239.255.255.250"
|
#define UPNP_MCAST_ADDR "239.255.255.250"
|
||||||
|
/* for IPv6 */
|
||||||
|
#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */
|
||||||
|
#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */
|
||||||
|
|
||||||
/* upnpDiscover() :
|
/* upnpDiscover() :
|
||||||
* return a chained list of all devices found or NULL if
|
* return a chained list of all devices found or NULL if
|
||||||
* no devices was found.
|
* no devices was found.
|
||||||
* It is up to the caller to free the chained list
|
* It is up to the caller to free the chained list
|
||||||
* delay is in millisecond (poll) */
|
* delay is in millisecond (poll) */
|
||||||
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
LIBSPEC struct UPNPDev *
|
||||||
const char * minissdpdsock, int sameport)
|
upnpDiscover(int delay, const char * multicastif,
|
||||||
|
const char * minissdpdsock, int sameport,
|
||||||
|
int ipv6,
|
||||||
|
int * error)
|
||||||
{
|
{
|
||||||
struct UPNPDev * tmp;
|
struct UPNPDev * tmp;
|
||||||
struct UPNPDev * devlist = 0;
|
struct UPNPDev * devlist = 0;
|
||||||
int opt = 1;
|
int opt = 1;
|
||||||
static const char MSearchMsgFmt[] =
|
static const char MSearchMsgFmt[] =
|
||||||
"M-SEARCH * HTTP/1.1\r\n"
|
"M-SEARCH * HTTP/1.1\r\n"
|
||||||
"HOST: " UPNP_MCAST_ADDR ":" XSTR(PORT) "\r\n"
|
"HOST: %s:" XSTR(PORT) "\r\n"
|
||||||
"ST: %s\r\n"
|
"ST: %s\r\n"
|
||||||
"MAN: \"ssdp:discover\"\r\n"
|
"MAN: \"ssdp:discover\"\r\n"
|
||||||
"MX: %u\r\n"
|
"MX: %u\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
static const char * const deviceList[] = {
|
static const char * const deviceList[] = {
|
||||||
|
#if 0
|
||||||
|
"urn:schemas-upnp-org:device:InternetGatewayDevice:2",
|
||||||
|
"urn:schemas-upnp-org:service:WANIPConnection:2",
|
||||||
|
#endif
|
||||||
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
|
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
|
||||||
"urn:schemas-upnp-org:service:WANIPConnection:1",
|
"urn:schemas-upnp-org:service:WANIPConnection:1",
|
||||||
"urn:schemas-upnp-org:service:WANPPPConnection:1",
|
"urn:schemas-upnp-org:service:WANPPPConnection:1",
|
||||||
@@ -419,14 +345,21 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
char bufr[1536]; /* reception and emission buffer */
|
char bufr[1536]; /* reception and emission buffer */
|
||||||
int sudp;
|
int sudp;
|
||||||
int n;
|
int n;
|
||||||
struct sockaddr sockudp_r;
|
struct sockaddr_storage sockudp_r;
|
||||||
unsigned int mx;
|
unsigned int mx;
|
||||||
|
#ifdef NO_GETADDRINFO
|
||||||
|
struct sockaddr_storage sockudp_w;
|
||||||
|
#else
|
||||||
int rv;
|
int rv;
|
||||||
struct addrinfo hints, *servinfo, *p;
|
struct addrinfo hints, *servinfo, *p;
|
||||||
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
MIB_IPFORWARDROW ip_forward;
|
MIB_IPFORWARDROW ip_forward;
|
||||||
#endif
|
#endif
|
||||||
|
int linklocal = 1;
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_UNKNOWN_ERROR;
|
||||||
#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
|
#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
/* first try to get infos from minissdpd ! */
|
/* first try to get infos from minissdpd ! */
|
||||||
if(!minissdpdsock)
|
if(!minissdpdsock)
|
||||||
@@ -435,31 +368,36 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
devlist = getDevicesFromMiniSSDPD(deviceList[deviceIndex],
|
devlist = getDevicesFromMiniSSDPD(deviceList[deviceIndex],
|
||||||
minissdpdsock);
|
minissdpdsock);
|
||||||
/* We return what we have found if it was not only a rootdevice */
|
/* We return what we have found if it was not only a rootdevice */
|
||||||
if(devlist && !strstr(deviceList[deviceIndex], "rootdevice"))
|
if(devlist && !strstr(deviceList[deviceIndex], "rootdevice")) {
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SUCCESS;
|
||||||
return devlist;
|
return devlist;
|
||||||
|
}
|
||||||
deviceIndex++;
|
deviceIndex++;
|
||||||
}
|
}
|
||||||
deviceIndex = 0;
|
deviceIndex = 0;
|
||||||
#endif
|
#endif
|
||||||
/* fallback to direct discovery */
|
/* fallback to direct discovery */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
sudp = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
#else
|
#else
|
||||||
sudp = socket(PF_INET, SOCK_DGRAM, 0);
|
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
|
||||||
#endif
|
#endif
|
||||||
if(sudp < 0)
|
if(sudp < 0)
|
||||||
{
|
{
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
PRINT_SOCKET_ERROR("socket");
|
PRINT_SOCKET_ERROR("socket");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* reception */
|
/* reception */
|
||||||
memset(&sockudp_r, 0, sizeof(struct sockaddr));
|
memset(&sockudp_r, 0, sizeof(struct sockaddr_storage));
|
||||||
if(0/*ipv6*/) {
|
if(ipv6) {
|
||||||
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
|
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
|
||||||
p->sin6_family = AF_INET6;
|
p->sin6_family = AF_INET6;
|
||||||
if(sameport)
|
if(sameport)
|
||||||
p->sin6_port = htons(PORT);
|
p->sin6_port = htons(PORT);
|
||||||
p->sin6_addr = in6addr_any;//IN6ADDR_ANY_INIT;/*INADDR_ANY;*/
|
p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
|
||||||
} else {
|
} else {
|
||||||
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
|
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
|
||||||
p->sin_family = AF_INET;
|
p->sin_family = AF_INET;
|
||||||
@@ -467,19 +405,13 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
p->sin_port = htons(PORT);
|
p->sin_port = htons(PORT);
|
||||||
p->sin_addr.s_addr = INADDR_ANY;
|
p->sin_addr.s_addr = INADDR_ANY;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
/* emission */
|
|
||||||
memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
|
|
||||||
sockudp_w.sin_family = AF_INET;
|
|
||||||
sockudp_w.sin_port = htons(PORT);
|
|
||||||
sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
|
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* This code could help us to use the right Network interface for
|
/* This code could help us to use the right Network interface for
|
||||||
* SSDP multicast traffic */
|
* SSDP multicast traffic */
|
||||||
/* Get IP associated with the index given in the ip_forward struct
|
/* Get IP associated with the index given in the ip_forward struct
|
||||||
* in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
|
* in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
|
||||||
if(GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR) {
|
if(!ipv6
|
||||||
|
&& (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) {
|
||||||
DWORD dwRetVal = 0;
|
DWORD dwRetVal = 0;
|
||||||
PMIB_IPADDRTABLE pIPAddrTable;
|
PMIB_IPADDRTABLE pIPAddrTable;
|
||||||
DWORD dwSize = 0;
|
DWORD dwSize = 0;
|
||||||
@@ -539,63 +471,113 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
|
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
PRINT_SOCKET_ERROR("setsockopt");
|
PRINT_SOCKET_ERROR("setsockopt");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(multicastif)
|
if(multicastif)
|
||||||
{
|
{
|
||||||
struct in_addr mc_if;
|
if(ipv6) {
|
||||||
mc_if.s_addr = inet_addr(multicastif);
|
#if !defined(WIN32)
|
||||||
if(0/*ipv6*/) {
|
/* according to MSDN, if_nametoindex() is supported since
|
||||||
|
* MS Windows Vista and MS Windows Server 2008.
|
||||||
|
* http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
|
||||||
|
unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
|
||||||
|
if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(&ifindex)) < 0)
|
||||||
|
{
|
||||||
|
PRINT_SOCKET_ERROR("setsockopt");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Setting of multicast interface not supported in IPv6 under Windows.\n");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
struct in_addr mc_if;
|
||||||
|
mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
|
||||||
((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
|
((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
|
||||||
}
|
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
|
||||||
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
|
{
|
||||||
{
|
PRINT_SOCKET_ERROR("setsockopt");
|
||||||
PRINT_SOCKET_ERROR("setsockopt");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avant d'envoyer le paquet on bind pour recevoir la reponse */
|
/* Avant d'envoyer le paquet on bind pour recevoir la reponse */
|
||||||
if (bind(sudp, &sockudp_r, 0/*ipv6*/?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) != 0)
|
if (bind(sudp, (const struct sockaddr *)&sockudp_r,
|
||||||
|
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0)
|
||||||
{
|
{
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
PRINT_SOCKET_ERROR("bind");
|
PRINT_SOCKET_ERROR("bind");
|
||||||
closesocket(sudp);
|
closesocket(sudp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SUCCESS;
|
||||||
/* Calculating maximum response time in seconds */
|
/* Calculating maximum response time in seconds */
|
||||||
mx = ((unsigned int)delay) / 1000u;
|
mx = ((unsigned int)delay) / 1000u;
|
||||||
/* receiving SSDP response packet */
|
/* receiving SSDP response packet */
|
||||||
for(n = 0;;)
|
for(n = 0; deviceList[deviceIndex]; deviceIndex++)
|
||||||
{
|
{
|
||||||
if(n == 0)
|
if(n == 0)
|
||||||
{
|
{
|
||||||
/* sending the SSDP M-SEARCH packet */
|
/* sending the SSDP M-SEARCH packet */
|
||||||
n = snprintf(bufr, sizeof(bufr),
|
n = snprintf(bufr, sizeof(bufr),
|
||||||
MSearchMsgFmt, deviceList[deviceIndex++], mx);
|
MSearchMsgFmt,
|
||||||
/*printf("Sending %s", bufr);*/
|
ipv6 ?
|
||||||
#if 0
|
(linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]")
|
||||||
n = sendto(sudp, bufr, n, 0,
|
: UPNP_MCAST_ADDR,
|
||||||
(struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));
|
deviceList[deviceIndex], mx);
|
||||||
if (n < 0) {
|
#ifdef DEBUG
|
||||||
PRINT_SOCKET_ERROR("sendto");
|
printf("Sending %s", bufr);
|
||||||
closesocket(sudp);
|
|
||||||
return devlist;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NO_GETADDRINFO
|
||||||
|
/* the following code is not using getaddrinfo */
|
||||||
|
/* emission */
|
||||||
|
memset(&sockudp_w, 0, sizeof(struct sockaddr_storage));
|
||||||
|
if(ipv6) {
|
||||||
|
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w;
|
||||||
|
p->sin6_family = AF_INET6;
|
||||||
|
p->sin6_port = htons(PORT);
|
||||||
|
inet_pton(AF_INET6,
|
||||||
|
linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR,
|
||||||
|
&(p->sin6_addr));
|
||||||
|
} else {
|
||||||
|
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w;
|
||||||
|
p->sin_family = AF_INET;
|
||||||
|
p->sin_port = htons(PORT);
|
||||||
|
p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
|
||||||
|
}
|
||||||
|
n = sendto(sudp, bufr, n, 0,
|
||||||
|
&sockudp_w,
|
||||||
|
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
|
||||||
|
if (n < 0) {
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
|
PRINT_SOCKET_ERROR("sendto");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else /* #ifdef NO_GETADDRINFO */
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET
|
hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
/*hints.ai_flags = */
|
/*hints.ai_flags = */
|
||||||
if ((rv = getaddrinfo(UPNP_MCAST_ADDR, XSTR(PORT), &hints, &servinfo)) != 0) {
|
if ((rv = getaddrinfo(ipv6
|
||||||
|
? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR)
|
||||||
|
: UPNP_MCAST_ADDR,
|
||||||
|
XSTR(PORT), &hints, &servinfo)) != 0) {
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
|
fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
||||||
#endif
|
#endif
|
||||||
return devlist;
|
break;
|
||||||
}
|
}
|
||||||
for(p = servinfo; p; p = p->ai_next) {
|
for(p = servinfo; p; p = p->ai_next) {
|
||||||
n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
|
n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
|
||||||
@@ -606,22 +588,34 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
}
|
}
|
||||||
freeaddrinfo(servinfo);
|
freeaddrinfo(servinfo);
|
||||||
if(n < 0) {
|
if(n < 0) {
|
||||||
closesocket(sudp);
|
if(error)
|
||||||
return devlist;
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
#endif /* #ifdef NO_GETADDRINFO */
|
||||||
}
|
}
|
||||||
/* Waiting for SSDP REPLY packet to M-SEARCH */
|
/* Waiting for SSDP REPLY packet to M-SEARCH */
|
||||||
n = ReceiveData(sudp, bufr, sizeof(bufr), delay);
|
n = receivedata(sudp, bufr, sizeof(bufr), delay);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
closesocket(sudp);
|
if(error)
|
||||||
return devlist;
|
*error = UPNPDISCOVER_SOCKET_ERROR;
|
||||||
|
break;
|
||||||
} else if (n == 0) {
|
} else if (n == 0) {
|
||||||
/* no data or Time Out */
|
/* no data or Time Out */
|
||||||
if (devlist || (deviceList[deviceIndex] == 0)) {
|
if (devlist) {
|
||||||
/* no more device type to look for... */
|
/* no more device type to look for... */
|
||||||
closesocket(sudp);
|
if(error)
|
||||||
return devlist;
|
*error = UPNPDISCOVER_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(ipv6) {
|
||||||
|
if(linklocal) {
|
||||||
|
linklocal = 0;
|
||||||
|
--deviceIndex;
|
||||||
|
} else {
|
||||||
|
linklocal = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const char * descURL=NULL;
|
const char * descURL=NULL;
|
||||||
@@ -648,6 +642,12 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
if(tmp)
|
if(tmp)
|
||||||
continue;
|
continue;
|
||||||
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
|
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
|
||||||
|
if(!tmp) {
|
||||||
|
/* memory allocation error */
|
||||||
|
if(error)
|
||||||
|
*error = UPNPDISCOVER_MEMORY_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
tmp->pNext = devlist;
|
tmp->pNext = devlist;
|
||||||
tmp->descURL = tmp->buffer;
|
tmp->descURL = tmp->buffer;
|
||||||
tmp->st = tmp->buffer + 1 + urlsize;
|
tmp->st = tmp->buffer + 1 + urlsize;
|
||||||
@@ -659,6 +659,8 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
closesocket(sudp);
|
||||||
|
return devlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* freeUPNPDevlist() should be used to
|
/* freeUPNPDevlist() should be used to
|
||||||
@@ -703,19 +705,21 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
|
|||||||
const char * descURL)
|
const char * descURL)
|
||||||
{
|
{
|
||||||
char * p;
|
char * p;
|
||||||
int n1, n2, n3;
|
int n1, n2, n3, n4;
|
||||||
n1 = strlen(data->urlbase);
|
n1 = strlen(data->urlbase);
|
||||||
if(n1==0)
|
if(n1==0)
|
||||||
n1 = strlen(descURL);
|
n1 = strlen(descURL);
|
||||||
n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
|
n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
|
||||||
n2 = n1; n3 = n1;
|
n2 = n1; n3 = n1; n4 = n1;
|
||||||
n1 += strlen(data->first.scpdurl);
|
n1 += strlen(data->first.scpdurl);
|
||||||
n2 += strlen(data->first.controlurl);
|
n2 += strlen(data->first.controlurl);
|
||||||
n3 += strlen(data->CIF.controlurl);
|
n3 += strlen(data->CIF.controlurl);
|
||||||
|
n4 += strlen(data->IPv6FC.controlurl);
|
||||||
|
|
||||||
urls->ipcondescURL = (char *)malloc(n1);
|
urls->ipcondescURL = (char *)malloc(n1);
|
||||||
urls->controlURL = (char *)malloc(n2);
|
urls->controlURL = (char *)malloc(n2);
|
||||||
urls->controlURL_CIF = (char *)malloc(n3);
|
urls->controlURL_CIF = (char *)malloc(n3);
|
||||||
|
urls->controlURL_6FC = (char *)malloc(n4);
|
||||||
/* maintenant on chope la desc du WANIPConnection */
|
/* maintenant on chope la desc du WANIPConnection */
|
||||||
if(data->urlbase[0] != '\0')
|
if(data->urlbase[0] != '\0')
|
||||||
strncpy(urls->ipcondescURL, data->urlbase, n1);
|
strncpy(urls->ipcondescURL, data->urlbase, n1);
|
||||||
@@ -725,6 +729,7 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
|
|||||||
if(p) p[0] = '\0';
|
if(p) p[0] = '\0';
|
||||||
strncpy(urls->controlURL, urls->ipcondescURL, n2);
|
strncpy(urls->controlURL, urls->ipcondescURL, n2);
|
||||||
strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
|
strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
|
||||||
|
strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4);
|
||||||
|
|
||||||
url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
|
url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
|
||||||
|
|
||||||
@@ -732,6 +737,8 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
|
|||||||
|
|
||||||
url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
|
url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
|
||||||
|
|
||||||
|
url_cpy_or_cat(urls->controlURL_6FC, data->IPv6FC.controlurl, n4);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL,
|
printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL,
|
||||||
(unsigned)strlen(urls->ipcondescURL), n1);
|
(unsigned)strlen(urls->ipcondescURL), n1);
|
||||||
@@ -739,6 +746,8 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
|
|||||||
(unsigned)strlen(urls->controlURL), n2);
|
(unsigned)strlen(urls->controlURL), n2);
|
||||||
printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
|
printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
|
||||||
(unsigned)strlen(urls->controlURL_CIF), n3);
|
(unsigned)strlen(urls->controlURL_CIF), n3);
|
||||||
|
printf("urls->controlURL_6FC='%s' %u n4=%d\n", urls->controlURL_6FC,
|
||||||
|
(unsigned)strlen(urls->controlURL_6FC), n4);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,56 +762,8 @@ FreeUPNPUrls(struct UPNPUrls * urls)
|
|||||||
urls->ipcondescURL = 0;
|
urls->ipcondescURL = 0;
|
||||||
free(urls->controlURL_CIF);
|
free(urls->controlURL_CIF);
|
||||||
urls->controlURL_CIF = 0;
|
urls->controlURL_CIF = 0;
|
||||||
}
|
free(urls->controlURL_6FC);
|
||||||
|
urls->controlURL_6FC = 0;
|
||||||
|
|
||||||
int ReceiveData(int socket, char * data, int length, int timeout)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
|
|
||||||
struct pollfd fds[1]; /* for the poll */
|
|
||||||
#ifdef MINIUPNPC_IGNORE_EINTR
|
|
||||||
do {
|
|
||||||
#endif
|
|
||||||
fds[0].fd = socket;
|
|
||||||
fds[0].events = POLLIN;
|
|
||||||
n = poll(fds, 1, timeout);
|
|
||||||
#ifdef MINIUPNPC_IGNORE_EINTR
|
|
||||||
} while(n < 0 && errno == EINTR);
|
|
||||||
#endif
|
|
||||||
if(n < 0)
|
|
||||||
{
|
|
||||||
PRINT_SOCKET_ERROR("poll");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if(n == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
fd_set socketSet;
|
|
||||||
TIMEVAL timeval;
|
|
||||||
FD_ZERO(&socketSet);
|
|
||||||
FD_SET(socket, &socketSet);
|
|
||||||
timeval.tv_sec = timeout / 1000;
|
|
||||||
timeval.tv_usec = (timeout % 1000) * 1000;
|
|
||||||
n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
|
|
||||||
if(n < 0)
|
|
||||||
{
|
|
||||||
PRINT_SOCKET_ERROR("select");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if(n == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
n = recv(socket, data, length, 0);
|
|
||||||
if(n<0)
|
|
||||||
{
|
|
||||||
PRINT_SOCKET_ERROR("recv");
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
@@ -26,6 +26,17 @@ EXPORTS
|
|||||||
UPNP_DeletePortMapping
|
UPNP_DeletePortMapping
|
||||||
UPNP_GetPortMappingNumberOfEntries
|
UPNP_GetPortMappingNumberOfEntries
|
||||||
UPNP_GetSpecificPortMappingEntry
|
UPNP_GetSpecificPortMappingEntry
|
||||||
UPNP_GetGenericPortMappingEntry
|
UPNP_GetGenericPortMappingEntry
|
||||||
|
UPNP_GetListOfPortMappings
|
||||||
|
UPNP_AddPinhole
|
||||||
|
UPNP_CheckPinholeWorking
|
||||||
|
UPNP_UpdatePinhole
|
||||||
|
UPNP_GetPinholePackets
|
||||||
|
UPNP_DeletePinhole
|
||||||
|
UPNP_GetFirewallStatus
|
||||||
|
UPNP_GetOutboundPinholeTimeout
|
||||||
; upnperrors
|
; upnperrors
|
||||||
strupnperror
|
strupnperror
|
||||||
|
; portlistingparse
|
||||||
|
ParsePortListing
|
||||||
|
FreePortListing
|
@@ -1,8 +1,8 @@
|
|||||||
/* $Id: miniupnpc.h,v 1.19 2009/10/10 19:15:35 nanard Exp $ */
|
/* $Id: miniupnpc.h,v 1.23 2011/04/11 08:21:46 nanard Exp $ */
|
||||||
/* Project: miniupnp
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2005-2006 Thomas Bernard
|
* Copyright (c) 2005-2011 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef __MINIUPNPC_H__
|
#ifndef __MINIUPNPC_H__
|
||||||
@@ -11,6 +11,12 @@
|
|||||||
#include "declspec.h"
|
#include "declspec.h"
|
||||||
#include "igd_desc_parse.h"
|
#include "igd_desc_parse.h"
|
||||||
|
|
||||||
|
/* error codes : */
|
||||||
|
#define UPNPDISCOVER_SUCCESS (0)
|
||||||
|
#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
|
||||||
|
#define UPNPDISCOVER_SOCKET_ERROR (-101)
|
||||||
|
#define UPNPDISCOVER_MEMORY_ERROR (-102)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -18,9 +24,10 @@ extern "C" {
|
|||||||
/* Structures definitions : */
|
/* Structures definitions : */
|
||||||
struct UPNParg { const char * elt; const char * val; };
|
struct UPNParg { const char * elt; const char * val; };
|
||||||
|
|
||||||
int simpleUPnPcommand(int, const char *, const char *,
|
char *
|
||||||
const char *, struct UPNParg *,
|
simpleUPnPcommand(int, const char *, const char *,
|
||||||
char *, int *);
|
const char *, struct UPNParg *,
|
||||||
|
int *);
|
||||||
|
|
||||||
struct UPNPDev {
|
struct UPNPDev {
|
||||||
struct UPNPDev * pNext;
|
struct UPNPDev * pNext;
|
||||||
@@ -42,8 +49,11 @@ struct UPNPDev {
|
|||||||
* multicast interface for sending SSDP discover packets.
|
* multicast interface for sending SSDP discover packets.
|
||||||
* If sameport is not null, SSDP packets will be sent from the source port
|
* If sameport is not null, SSDP packets will be sent from the source port
|
||||||
* 1900 (same as destination port) otherwise system assign a source port. */
|
* 1900 (same as destination port) otherwise system assign a source port. */
|
||||||
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
|
LIBSPEC struct UPNPDev *
|
||||||
const char * minissdpdsock, int sameport);
|
upnpDiscover(int delay, const char * multicastif,
|
||||||
|
const char * minissdpdsock, int sameport,
|
||||||
|
int ipv6,
|
||||||
|
int * error);
|
||||||
/* freeUPNPDevlist()
|
/* freeUPNPDevlist()
|
||||||
* free list returned by upnpDiscover() */
|
* free list returned by upnpDiscover() */
|
||||||
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
|
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
|
||||||
@@ -57,11 +67,13 @@ LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
|
|||||||
* controlURL: controlURL of the WANIPConnection
|
* controlURL: controlURL of the WANIPConnection
|
||||||
* ipcondescURL: url of the description of the WANIPConnection
|
* ipcondescURL: url of the description of the WANIPConnection
|
||||||
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
|
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
|
||||||
|
* controlURL_6FC: controlURL of the WANIPv6FirewallControl
|
||||||
*/
|
*/
|
||||||
struct UPNPUrls {
|
struct UPNPUrls {
|
||||||
char * controlURL;
|
char * controlURL;
|
||||||
char * ipcondescURL;
|
char * ipcondescURL;
|
||||||
char * controlURL_CIF;
|
char * controlURL_CIF;
|
||||||
|
char * controlURL_6FC;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* UPNP_GetValidIGD() :
|
/* UPNP_GetValidIGD() :
|
||||||
@@ -97,11 +109,6 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);
|
|||||||
|
|
||||||
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
|
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
|
||||||
|
|
||||||
/* Reads data from the specified socket.
|
|
||||||
* Returns the number of bytes read if successful, zero if no bytes were
|
|
||||||
* read or if we timed out. Returns negative if there was an error. */
|
|
||||||
int ReceiveData(int socket, char * data, int length, int timeout);
|
|
||||||
|
|
||||||
/* return 0 or 1 */
|
/* return 0 or 1 */
|
||||||
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
|
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: miniupnpcmodule.c,v 1.15 2010/06/09 10:23:01 nanard Exp $*/
|
/* $Id: miniupnpcmodule.c,v 1.18 2011/04/10 11:21:23 nanard Exp $*/
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
* website : http://miniupnp.tuxfamily.org/
|
* website : http://miniupnp.tuxfamily.org/
|
||||||
@@ -32,7 +32,7 @@ typedef struct {
|
|||||||
struct UPNPUrls urls;
|
struct UPNPUrls urls;
|
||||||
struct IGDdatas data;
|
struct IGDdatas data;
|
||||||
unsigned int discoverdelay; /* value passed to upnpDiscover() */
|
unsigned int discoverdelay; /* value passed to upnpDiscover() */
|
||||||
char lanaddr[16]; /* our ip address on the LAN */
|
char lanaddr[40]; /* our ip address on the LAN */
|
||||||
char * multicastif;
|
char * multicastif;
|
||||||
char * minissdpdsocket;
|
char * minissdpdsocket;
|
||||||
} UPnPObject;
|
} UPnPObject;
|
||||||
@@ -77,7 +77,9 @@ UPnP_discover(UPnPObject *self)
|
|||||||
self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
|
self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
|
||||||
0/* multicast if*/,
|
0/* multicast if*/,
|
||||||
0/*minissdpd socket*/,
|
0/*minissdpd socket*/,
|
||||||
0/*sameport flag*/);
|
0/*sameport flag*/,
|
||||||
|
0/*ip v6*/,
|
||||||
|
0/*error */);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
/* Py_RETURN_NONE ??? */
|
/* Py_RETURN_NONE ??? */
|
||||||
for(dev = self->devlist, i = 0; dev; dev = dev->pNext)
|
for(dev = self->devlist, i = 0; dev; dev = dev->pNext)
|
||||||
@@ -195,7 +197,7 @@ Py_END_ALLOW_THREADS
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
UPnP_externalipaddress(UPnPObject *self)
|
UPnP_externalipaddress(UPnPObject *self)
|
||||||
{
|
{
|
||||||
char externalIPAddress[16];
|
char externalIPAddress[40];
|
||||||
int r;
|
int r;
|
||||||
externalIPAddress[0] = '\0';
|
externalIPAddress[0] = '\0';
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
@@ -226,6 +228,7 @@ UPnP_addportmapping(UPnPObject *self, PyObject *args)
|
|||||||
const char * host;
|
const char * host;
|
||||||
const char * desc;
|
const char * desc;
|
||||||
const char * remoteHost;
|
const char * remoteHost;
|
||||||
|
const char * leaseDuration = "0";
|
||||||
int r;
|
int r;
|
||||||
if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto,
|
if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto,
|
||||||
&host, &iPort, &desc, &remoteHost))
|
&host, &iPort, &desc, &remoteHost))
|
||||||
@@ -234,7 +237,8 @@ Py_BEGIN_ALLOW_THREADS
|
|||||||
sprintf(extPort, "%hu", ePort);
|
sprintf(extPort, "%hu", ePort);
|
||||||
sprintf(inPort, "%hu", iPort);
|
sprintf(inPort, "%hu", iPort);
|
||||||
r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype,
|
r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype,
|
||||||
extPort, inPort, host, desc, proto, remoteHost);
|
extPort, inPort, host, desc, proto,
|
||||||
|
remoteHost, leaseDuration);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if(r==UPNPCOMMAND_SUCCESS)
|
if(r==UPNPCOMMAND_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -304,22 +308,31 @@ UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
|
|||||||
char extPort[6];
|
char extPort[6];
|
||||||
unsigned short ePort;
|
unsigned short ePort;
|
||||||
const char * proto;
|
const char * proto;
|
||||||
char intClient[16];
|
char intClient[40];
|
||||||
char intPort[6];
|
char intPort[6];
|
||||||
unsigned short iPort;
|
unsigned short iPort;
|
||||||
|
char desc[80];
|
||||||
|
char enabled[4];
|
||||||
|
char leaseDuration[16];
|
||||||
if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto))
|
if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0';
|
||||||
|
desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0';
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
sprintf(extPort, "%hu", ePort);
|
sprintf(extPort, "%hu", ePort);
|
||||||
UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
|
UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
|
||||||
self->data.first.servicetype,
|
self->data.first.servicetype,
|
||||||
extPort, proto,
|
extPort, proto,
|
||||||
intClient, intPort);
|
intClient, intPort,
|
||||||
|
desc, enabled, leaseDuration);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if(intClient[0])
|
if(intClient[0])
|
||||||
{
|
{
|
||||||
iPort = (unsigned short)atoi(intPort);
|
iPort = (unsigned short)atoi(intPort);
|
||||||
return Py_BuildValue("(s,H)", intClient, iPort);
|
return Py_BuildValue("(s,H,s,O,i)",
|
||||||
|
intClient, iPort, desc,
|
||||||
|
PyBool_FromLong(atoi(enabled)),
|
||||||
|
atoi(leaseDuration));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -333,7 +346,7 @@ UPnP_getgenericportmapping(UPnPObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
char index[8];
|
char index[8];
|
||||||
char intClient[16];
|
char intClient[40];
|
||||||
char intPort[6];
|
char intPort[6];
|
||||||
unsigned short iPort;
|
unsigned short iPort;
|
||||||
char extPort[6];
|
char extPort[6];
|
@@ -1,15 +1,15 @@
|
|||||||
/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
|
/* $Id: miniupnpcstrings.h.in,v 1.4 2011/01/04 11:41:53 nanard Exp $ */
|
||||||
/* Project: miniupnp
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2005-2009 Thomas Bernard
|
* Copyright (c) 2005-2011 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef __MINIUPNPCSTRINGS_H__
|
#ifndef __MINIUPNPCSTRINGS_H__
|
||||||
#define __MINIUPNPCSTRINGS_H__
|
#define __MINIUPNPCSTRINGS_H__
|
||||||
|
|
||||||
#define OS_STRING "Linux/2.6.35-ARCH"
|
#define OS_STRING "Linux/3.0-ARCH"
|
||||||
#define MINIUPNPC_VERSION_STRING "1.4"
|
#define MINIUPNPC_VERSION_STRING "1.6"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
7
thirdparty/libportfwd/third-party/miniupnpc-1.6/miniupnpcstrings.h.cmake
vendored
Normal file
7
thirdparty/libportfwd/third-party/miniupnpc-1.6/miniupnpcstrings.h.cmake
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef __MINIUPNPCSTRINGS_H__
|
||||||
|
#define __MINIUPNPCSTRINGS_H__
|
||||||
|
|
||||||
|
#define OS_STRING "${CMAKE_SYSTEM_NAME}"
|
||||||
|
#define MINIUPNPC_VERSION_STRING "${MINIUPNPC_VERSION}"
|
||||||
|
|
||||||
|
#endif
|
@@ -1,15 +1,15 @@
|
|||||||
/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
|
/* $Id: miniupnpcstrings.h.in,v 1.4 2011/01/04 11:41:53 nanard Exp $ */
|
||||||
/* Project: miniupnp
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2005-2009 Thomas Bernard
|
* Copyright (c) 2005-2011 Thomas Bernard
|
||||||
* This software is subjects to the conditions detailed
|
* This software is subjects to the conditions detailed
|
||||||
* in the LICENCE file provided within this distribution */
|
* in the LICENCE file provided within this distribution */
|
||||||
#ifndef __MINIUPNPCSTRINGS_H__
|
#ifndef __MINIUPNPCSTRINGS_H__
|
||||||
#define __MINIUPNPCSTRINGS_H__
|
#define __MINIUPNPCSTRINGS_H__
|
||||||
|
|
||||||
#define OS_STRING "OS/version"
|
#define OS_STRING "OS/version"
|
||||||
#define MINIUPNPC_VERSION_STRING "1.4"
|
#define MINIUPNPC_VERSION_STRING "version"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
19
thirdparty/libportfwd/third-party/miniupnpc-1.6/miniupnpctypes.h
vendored
Normal file
19
thirdparty/libportfwd/third-party/miniupnpc-1.6/miniupnpctypes.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 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__
|
||||||
|
#define __MINIUPNPCTYPES_H__
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
522
thirdparty/libportfwd/third-party/miniupnpc-1.6/miniwget.c
vendored
Normal file
522
thirdparty/libportfwd/third-party/miniupnpc-1.6/miniwget.c
vendored
Normal file
@@ -0,0 +1,522 @@
|
|||||||
|
/* $Id: miniwget.c,v 1.52 2011/06/17 22:59:42 nanard Exp $ */
|
||||||
|
/* Project : miniupnp
|
||||||
|
* Author : Thomas Bernard
|
||||||
|
* Copyright (c) 2005-2011 Thomas Bernard
|
||||||
|
* This software is subject to the conditions detailed in the
|
||||||
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <io.h>
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define socklen_t int
|
||||||
|
#ifndef strncasecmp
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
#define strncasecmp _memicmp
|
||||||
|
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
|
#define strncasecmp memicmp
|
||||||
|
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
|
||||||
|
#endif /* #ifndef strncasecmp */
|
||||||
|
#else /* #ifdef WIN32 */
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
|
#define socklen_t int
|
||||||
|
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#define closesocket close
|
||||||
|
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
||||||
|
* during the connect() call */
|
||||||
|
#define MINIUPNPC_IGNORE_EINTR
|
||||||
|
#endif /* #else WIN32 */
|
||||||
|
#if defined(__sun) || defined(sun)
|
||||||
|
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "miniupnpcstrings.h"
|
||||||
|
#include "miniwget.h"
|
||||||
|
#include "connecthostport.h"
|
||||||
|
#include "receivedata.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a HTTP response from a socket.
|
||||||
|
* Process Content-Length and Transfer-encoding headers.
|
||||||
|
* return a pointer to the content buffer, which length is saved
|
||||||
|
* to the length parameter.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
getHTTPResponse(int s, int * size)
|
||||||
|
{
|
||||||
|
char buf[2048];
|
||||||
|
int n;
|
||||||
|
int endofheaders = 0;
|
||||||
|
int chunked = 0;
|
||||||
|
int content_length = -1;
|
||||||
|
unsigned int chunksize = 0;
|
||||||
|
unsigned int bytestocopy = 0;
|
||||||
|
/* buffers : */
|
||||||
|
char * header_buf;
|
||||||
|
int header_buf_len = 2048;
|
||||||
|
int header_buf_used = 0;
|
||||||
|
char * content_buf;
|
||||||
|
int content_buf_len = 2048;
|
||||||
|
int content_buf_used = 0;
|
||||||
|
char chunksize_buf[32];
|
||||||
|
int chunksize_buf_index;
|
||||||
|
|
||||||
|
header_buf = malloc(header_buf_len);
|
||||||
|
content_buf = malloc(content_buf_len);
|
||||||
|
chunksize_buf[0] = '\0';
|
||||||
|
chunksize_buf_index = 0;
|
||||||
|
|
||||||
|
while((n = receivedata(s, buf, 2048, 5000)) > 0)
|
||||||
|
{
|
||||||
|
if(endofheaders == 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int linestart=0;
|
||||||
|
int colon=0;
|
||||||
|
int valuestart=0;
|
||||||
|
if(header_buf_used + n > header_buf_len) {
|
||||||
|
header_buf = realloc(header_buf, header_buf_used + n);
|
||||||
|
header_buf_len = header_buf_used + n;
|
||||||
|
}
|
||||||
|
memcpy(header_buf + header_buf_used, buf, n);
|
||||||
|
header_buf_used += n;
|
||||||
|
/* search for CR LF CR LF (end of headers)
|
||||||
|
* recognize also LF LF */
|
||||||
|
i = 0;
|
||||||
|
while(i < (header_buf_used-1) && (endofheaders == 0)) {
|
||||||
|
if(header_buf[i] == '\r') {
|
||||||
|
i++;
|
||||||
|
if(header_buf[i] == '\n') {
|
||||||
|
i++;
|
||||||
|
if(i < header_buf_used && header_buf[i] == '\r') {
|
||||||
|
i++;
|
||||||
|
if(i < header_buf_used && header_buf[i] == '\n') {
|
||||||
|
endofheaders = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(header_buf[i] == '\n') {
|
||||||
|
i++;
|
||||||
|
if(header_buf[i] == '\n') {
|
||||||
|
endofheaders = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(endofheaders == 0)
|
||||||
|
continue;
|
||||||
|
/* parse header lines */
|
||||||
|
for(i = 0; i < endofheaders - 1; i++) {
|
||||||
|
if(colon <= linestart && header_buf[i]==':')
|
||||||
|
{
|
||||||
|
colon = i;
|
||||||
|
while(i < (endofheaders-1)
|
||||||
|
&& (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
|
||||||
|
i++;
|
||||||
|
valuestart = i + 1;
|
||||||
|
}
|
||||||
|
/* detecting end of line */
|
||||||
|
else if(header_buf[i]=='\r' || header_buf[i]=='\n')
|
||||||
|
{
|
||||||
|
if(colon > linestart && valuestart > colon)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("header='%.*s', value='%.*s'\n",
|
||||||
|
colon-linestart, header_buf+linestart,
|
||||||
|
i-valuestart, header_buf+valuestart);
|
||||||
|
#endif
|
||||||
|
if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
|
||||||
|
{
|
||||||
|
content_length = atoi(header_buf+valuestart);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Content-Length: %d\n", content_length);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
|
||||||
|
&& 0==strncasecmp(header_buf+valuestart, "chunked", 7))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("chunked transfer-encoding!\n");
|
||||||
|
#endif
|
||||||
|
chunked = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(header_buf[i]=='\r' || header_buf[i] == '\n')
|
||||||
|
i++;
|
||||||
|
linestart = i;
|
||||||
|
colon = linestart;
|
||||||
|
valuestart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* copy the remaining of the received data back to buf */
|
||||||
|
n = header_buf_used - endofheaders;
|
||||||
|
memcpy(buf, header_buf + endofheaders, n);
|
||||||
|
/* if(headers) */
|
||||||
|
}
|
||||||
|
if(endofheaders)
|
||||||
|
{
|
||||||
|
/* content */
|
||||||
|
if(chunked)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while(i < n)
|
||||||
|
{
|
||||||
|
if(chunksize == 0)
|
||||||
|
{
|
||||||
|
/* reading chunk size */
|
||||||
|
if(chunksize_buf_index == 0) {
|
||||||
|
/* skipping any leading CR LF */
|
||||||
|
if(i<n && buf[i] == '\r') i++;
|
||||||
|
if(i<n && buf[i] == '\n') i++;
|
||||||
|
}
|
||||||
|
while(i<n && isxdigit(buf[i])
|
||||||
|
&& chunksize_buf_index < (sizeof(chunksize_buf)-1))
|
||||||
|
{
|
||||||
|
chunksize_buf[chunksize_buf_index++] = buf[i];
|
||||||
|
chunksize_buf[chunksize_buf_index] = '\0';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while(i<n && buf[i] != '\r' && buf[i] != '\n')
|
||||||
|
i++; /* discarding chunk-extension */
|
||||||
|
if(i<n && buf[i] == '\r') i++;
|
||||||
|
if(i<n && buf[i] == '\n') {
|
||||||
|
int j;
|
||||||
|
for(j = 0; j < chunksize_buf_index; j++) {
|
||||||
|
if(chunksize_buf[j] >= '0'
|
||||||
|
&& chunksize_buf[j] <= '9')
|
||||||
|
chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
|
||||||
|
else
|
||||||
|
chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
|
||||||
|
}
|
||||||
|
chunksize_buf[0] = '\0';
|
||||||
|
chunksize_buf_index = 0;
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
/* not finished to get chunksize */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("chunksize = %u (%x)\n", chunksize, chunksize);
|
||||||
|
#endif
|
||||||
|
if(chunksize == 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("end of HTTP content - %d %d\n", i, n);
|
||||||
|
/*printf("'%.*s'\n", n-i, buf+i);*/
|
||||||
|
#endif
|
||||||
|
goto end_of_stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i);
|
||||||
|
if((int)(content_buf_used + bytestocopy) > content_buf_len)
|
||||||
|
{
|
||||||
|
if(content_length >= content_buf_used + (int)bytestocopy) {
|
||||||
|
content_buf_len = content_length;
|
||||||
|
} else {
|
||||||
|
content_buf_len = content_buf_used + (int)bytestocopy;
|
||||||
|
}
|
||||||
|
content_buf = (char *)realloc((void *)content_buf,
|
||||||
|
content_buf_len);
|
||||||
|
}
|
||||||
|
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
|
||||||
|
content_buf_used += bytestocopy;
|
||||||
|
i += bytestocopy;
|
||||||
|
chunksize -= bytestocopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* not chunked */
|
||||||
|
if(content_length > 0
|
||||||
|
&& (content_buf_used + n) > content_length) {
|
||||||
|
/* skipping additional bytes */
|
||||||
|
n = content_length - content_buf_used;
|
||||||
|
}
|
||||||
|
if(content_buf_used + n > content_buf_len)
|
||||||
|
{
|
||||||
|
if(content_length >= content_buf_used + n) {
|
||||||
|
content_buf_len = content_length;
|
||||||
|
} else {
|
||||||
|
content_buf_len = content_buf_used + n;
|
||||||
|
}
|
||||||
|
content_buf = (char *)realloc((void *)content_buf,
|
||||||
|
content_buf_len);
|
||||||
|
}
|
||||||
|
memcpy(content_buf + content_buf_used, buf, n);
|
||||||
|
content_buf_used += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* use the Content-Length header value if available */
|
||||||
|
if(content_length > 0 && content_buf_used >= content_length)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("End of HTTP content\n");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end_of_stream:
|
||||||
|
free(header_buf); header_buf = NULL;
|
||||||
|
*size = content_buf_used;
|
||||||
|
if(content_buf_used == 0)
|
||||||
|
{
|
||||||
|
free(content_buf);
|
||||||
|
content_buf = NULL;
|
||||||
|
}
|
||||||
|
return content_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* miniwget3() :
|
||||||
|
* do all the work.
|
||||||
|
* Return NULL if something failed. */
|
||||||
|
static void *
|
||||||
|
miniwget3(const char * url, const char * host,
|
||||||
|
unsigned short port, const char * path,
|
||||||
|
int * size, char * addr_str, int addr_str_len,
|
||||||
|
const char * httpversion)
|
||||||
|
{
|
||||||
|
char buf[2048];
|
||||||
|
int s;
|
||||||
|
int n;
|
||||||
|
int len;
|
||||||
|
int sent;
|
||||||
|
void * content;
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
s = connecthostport(host, port);
|
||||||
|
if(s < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* get address for caller ! */
|
||||||
|
if(addr_str)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage saddr;
|
||||||
|
socklen_t saddrlen;
|
||||||
|
|
||||||
|
saddrlen = sizeof(saddr);
|
||||||
|
if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
|
||||||
|
{
|
||||||
|
perror("getsockname");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
|
/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
|
||||||
|
* But his function make a string with the port : nn.nn.nn.nn:port */
|
||||||
|
/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
|
||||||
|
NULL, addr_str, (DWORD *)&addr_str_len))
|
||||||
|
{
|
||||||
|
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
|
||||||
|
}*/
|
||||||
|
/* the following code is only compatible with ip v4 addresses */
|
||||||
|
strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
|
||||||
|
#else
|
||||||
|
#if 0
|
||||||
|
if(saddr.sa_family == AF_INET6) {
|
||||||
|
inet_ntop(AF_INET6,
|
||||||
|
&(((struct sockaddr_in6 *)&saddr)->sin6_addr),
|
||||||
|
addr_str, addr_str_len);
|
||||||
|
} else {
|
||||||
|
inet_ntop(AF_INET,
|
||||||
|
&(((struct sockaddr_in *)&saddr)->sin_addr),
|
||||||
|
addr_str, addr_str_len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* getnameinfo return ip v6 address with the scope identifier
|
||||||
|
* such as : 2a01:e35:8b2b:7330::%4281128194 */
|
||||||
|
n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
|
||||||
|
addr_str, addr_str_len,
|
||||||
|
NULL, 0,
|
||||||
|
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
|
if(n != 0) {
|
||||||
|
#ifdef WIN32
|
||||||
|
fprintf(stderr, "getnameinfo() failed : %d\n", n);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("address miniwget : %s\n", addr_str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf),
|
||||||
|
"GET %s HTTP/%s\r\n"
|
||||||
|
"Host: %s:%d\r\n"
|
||||||
|
"Connection: Close\r\n"
|
||||||
|
"User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
|
||||||
|
|
||||||
|
"\r\n",
|
||||||
|
path, httpversion, host, port);
|
||||||
|
sent = 0;
|
||||||
|
/* sending the HTTP request */
|
||||||
|
while(sent < len)
|
||||||
|
{
|
||||||
|
n = send(s, buf+sent, len-sent, 0);
|
||||||
|
if(n < 0)
|
||||||
|
{
|
||||||
|
perror("send");
|
||||||
|
closesocket(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sent += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content = getHTTPResponse(s, size);
|
||||||
|
closesocket(s);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* miniwget2() :
|
||||||
|
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
|
||||||
|
static void *
|
||||||
|
miniwget2(const char * url, const char * host,
|
||||||
|
unsigned short port, const char * path,
|
||||||
|
int * size, char * addr_str, int addr_str_len)
|
||||||
|
{
|
||||||
|
char * respbuffer;
|
||||||
|
|
||||||
|
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
|
||||||
|
/*
|
||||||
|
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
|
||||||
|
if (*size == 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Retrying with HTTP/1.1\n");
|
||||||
|
#endif
|
||||||
|
free(respbuffer);
|
||||||
|
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return respbuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* parseURL()
|
||||||
|
* arguments :
|
||||||
|
* url : source string not modified
|
||||||
|
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
|
||||||
|
* port : port (destination)
|
||||||
|
* path : pointer to the path part of the URL
|
||||||
|
*
|
||||||
|
* Return values :
|
||||||
|
* 0 - Failure
|
||||||
|
* 1 - Success */
|
||||||
|
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
|
||||||
|
{
|
||||||
|
char * p1, *p2, *p3;
|
||||||
|
if(!url)
|
||||||
|
return 0;
|
||||||
|
p1 = strstr(url, "://");
|
||||||
|
if(!p1)
|
||||||
|
return 0;
|
||||||
|
p1 += 3;
|
||||||
|
if( (url[0]!='h') || (url[1]!='t')
|
||||||
|
||(url[2]!='t') || (url[3]!='p'))
|
||||||
|
return 0;
|
||||||
|
memset(hostname, 0, MAXHOSTNAMELEN + 1);
|
||||||
|
if(*p1 == '[')
|
||||||
|
{
|
||||||
|
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
|
||||||
|
p2 = strchr(p1, ']');
|
||||||
|
p3 = strchr(p1, '/');
|
||||||
|
if(p2 && p3)
|
||||||
|
{
|
||||||
|
p2++;
|
||||||
|
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
|
||||||
|
if(*p2 == ':')
|
||||||
|
{
|
||||||
|
*port = 0;
|
||||||
|
p2++;
|
||||||
|
while( (*p2 >= '0') && (*p2 <= '9'))
|
||||||
|
{
|
||||||
|
*port *= 10;
|
||||||
|
*port += (unsigned short)(*p2 - '0');
|
||||||
|
p2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*port = 80;
|
||||||
|
}
|
||||||
|
*path = p3;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p2 = strchr(p1, ':');
|
||||||
|
p3 = strchr(p1, '/');
|
||||||
|
if(!p3)
|
||||||
|
return 0;
|
||||||
|
if(!p2 || (p2>p3))
|
||||||
|
{
|
||||||
|
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
|
||||||
|
*port = 80;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
|
||||||
|
*port = 0;
|
||||||
|
p2++;
|
||||||
|
while( (*p2 >= '0') && (*p2 <= '9'))
|
||||||
|
{
|
||||||
|
*port *= 10;
|
||||||
|
*port += (unsigned short)(*p2 - '0');
|
||||||
|
p2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*path = p3;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * miniwget(const char * url, int * size)
|
||||||
|
{
|
||||||
|
unsigned short port;
|
||||||
|
char * path;
|
||||||
|
/* protocol://host:port/chemin */
|
||||||
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
|
*size = 0;
|
||||||
|
if(!parseURL(url, hostname, &port, &path))
|
||||||
|
return NULL;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
|
||||||
|
#endif
|
||||||
|
return miniwget2(url, hostname, port, path, size, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
|
||||||
|
{
|
||||||
|
unsigned short port;
|
||||||
|
char * path;
|
||||||
|
/* protocol://host:port/chemin */
|
||||||
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
|
*size = 0;
|
||||||
|
if(addr)
|
||||||
|
addr[0] = '\0';
|
||||||
|
if(!parseURL(url, hostname, &port, &path))
|
||||||
|
return NULL;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
|
||||||
|
#endif
|
||||||
|
return miniwget2(url, hostname, port, path, size, addr, addrlen);
|
||||||
|
}
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: miniwget.h,v 1.5 2007/01/29 20:27:23 nanard Exp $ */
|
/* $Id: miniwget.h,v 1.6 2010/12/09 16:11:33 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005 Thomas Bernard
|
* Copyright (c) 2005 Thomas Bernard
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
LIBSPEC void * getHTTPResponse(int s, int * size);
|
||||||
|
|
||||||
LIBSPEC void * miniwget(const char *, int *);
|
LIBSPEC void * miniwget(const char *, int *);
|
||||||
|
|
||||||
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
|
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
|
@@ -1,10 +1,10 @@
|
|||||||
/* $Id: minixml.c,v 1.7 2009/10/10 19:15:35 nanard Exp $ */
|
/* $Id: minixml.c,v 1.9 2011/02/07 13:44:57 nanard Exp $ */
|
||||||
/* minixml.c : the minimum size a xml parser can be ! */
|
/* minixml.c : the minimum size a xml parser can be ! */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
|
|
||||||
Copyright (c) 2005-2009, Thomas BERNARD
|
Copyright (c) 2005-2011, Thomas BERNARD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -30,6 +30,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
#include <string.h>
|
||||||
#include "minixml.h"
|
#include "minixml.h"
|
||||||
|
|
||||||
/* parseatt : used to parse the argument list
|
/* parseatt : used to parse the argument list
|
||||||
@@ -142,19 +143,43 @@ static void parseelt(struct xmlparser * p)
|
|||||||
if (p->xml >= p->xmlend)
|
if (p->xml >= p->xmlend)
|
||||||
return;
|
return;
|
||||||
while( IS_WHITE_SPACE(*p->xml) )
|
while( IS_WHITE_SPACE(*p->xml) )
|
||||||
{
|
|
||||||
p->xml++;
|
|
||||||
if (p->xml >= p->xmlend)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while(*p->xml!='<')
|
|
||||||
{
|
{
|
||||||
i++; p->xml++;
|
i++; p->xml++;
|
||||||
if (p->xml >= p->xmlend)
|
if (p->xml >= p->xmlend)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(i>0 && p->datafunc)
|
if(memcmp(p->xml, "<![CDATA[", 9) == 0)
|
||||||
p->datafunc(p->data, data, i);
|
{
|
||||||
|
/* CDATA handling */
|
||||||
|
p->xml += 9;
|
||||||
|
data = p->xml;
|
||||||
|
i = 0;
|
||||||
|
while(memcmp(p->xml, "]]>", 3) != 0)
|
||||||
|
{
|
||||||
|
i++; p->xml++;
|
||||||
|
if ((p->xml + 3) >= p->xmlend)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(i>0 && p->datafunc)
|
||||||
|
p->datafunc(p->data, data, i);
|
||||||
|
while(*p->xml!='<')
|
||||||
|
{
|
||||||
|
p->xml++;
|
||||||
|
if (p->xml >= p->xmlend)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(*p->xml!='<')
|
||||||
|
{
|
||||||
|
i++; p->xml++;
|
||||||
|
if ((p->xml + 1) >= p->xmlend)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(i>0 && p->datafunc && *(p->xml + 1) == '/')
|
||||||
|
p->datafunc(p->data, data, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(*p->xml == '/')
|
else if(*p->xml == '/')
|
@@ -1,10 +1,10 @@
|
|||||||
/* $Id: minixmlvalid.c,v 1.2 2006/11/30 11:31:55 nanard Exp $ */
|
/* $Id: minixmlvalid.c,v 1.4 2011/02/07 13:44:57 nanard Exp $ */
|
||||||
/* MiniUPnP Project
|
/* MiniUPnP Project
|
||||||
* http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
|
* http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
|
||||||
* minixmlvalid.c :
|
* minixmlvalid.c :
|
||||||
* validation program for the minixml parser
|
* validation program for the minixml parser
|
||||||
*
|
*
|
||||||
* (c) 2006 Thomas Bernard */
|
* (c) 2006-2011 Thomas Bernard */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -30,7 +30,10 @@ int evtlistcmp(struct eventlist * a, struct eventlist * b)
|
|||||||
int i;
|
int i;
|
||||||
struct event * ae, * be;
|
struct event * ae, * be;
|
||||||
if(a->n != b->n)
|
if(a->n != b->n)
|
||||||
return 1;
|
{
|
||||||
|
printf("event number not matching : %d != %d\n", a->n, b->n);
|
||||||
|
//return 1;
|
||||||
|
}
|
||||||
for(i=0; i<a->n; i++)
|
for(i=0; i<a->n; i++)
|
||||||
{
|
{
|
||||||
ae = a->events + i;
|
ae = a->events + i;
|
||||||
@@ -55,7 +58,8 @@ static const char xmldata[] =
|
|||||||
"character data"
|
"character data"
|
||||||
"</elt1> \n \t"
|
"</elt1> \n \t"
|
||||||
"<elt1b/>"
|
"<elt1b/>"
|
||||||
"<elt2a> \t<elt2b>chardata1</elt2b><elt2b>chardata2</elt2b></elt2a>"
|
"<elt1>\n<![CDATA[ <html>stuff !\n ]]> \n</elt1>\n"
|
||||||
|
"<elt2a> \t<elt2b>chardata1</elt2b><elt2b> chardata2 </elt2b></elt2a>"
|
||||||
"</xmlroot>";
|
"</xmlroot>";
|
||||||
|
|
||||||
static const struct event evtref[] =
|
static const struct event evtref[] =
|
||||||
@@ -66,12 +70,15 @@ static const struct event evtref[] =
|
|||||||
{CHARDATA, "character data", 14},
|
{CHARDATA, "character data", 14},
|
||||||
{ELTEND, "elt1", 4},
|
{ELTEND, "elt1", 4},
|
||||||
{ELTSTART, "elt1b", 5},
|
{ELTSTART, "elt1b", 5},
|
||||||
|
{ELTSTART, "elt1", 4},
|
||||||
|
{CHARDATA, " <html>stuff !\n ", 16},
|
||||||
|
{ELTEND, "elt1", 4},
|
||||||
{ELTSTART, "elt2a", 5},
|
{ELTSTART, "elt2a", 5},
|
||||||
{ELTSTART, "elt2b", 5},
|
{ELTSTART, "elt2b", 5},
|
||||||
{CHARDATA, "chardata1", 9},
|
{CHARDATA, "chardata1", 9},
|
||||||
{ELTEND, "elt2b", 5},
|
{ELTEND, "elt2b", 5},
|
||||||
{ELTSTART, "elt2b", 5},
|
{ELTSTART, "elt2b", 5},
|
||||||
{CHARDATA, "chardata2", 9},
|
{CHARDATA, " chardata2 ", 11},
|
||||||
{ELTEND, "elt2b", 5},
|
{ELTEND, "elt2b", 5},
|
||||||
{ELTEND, "elt2a", 5},
|
{ELTEND, "elt2a", 5},
|
||||||
{ELTEND, "xmlroot", 7}
|
{ELTEND, "xmlroot", 7}
|
157
thirdparty/libportfwd/third-party/miniupnpc-1.6/portlistingparse.c
vendored
Normal file
157
thirdparty/libportfwd/third-party/miniupnpc-1.6/portlistingparse.c
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/* $Id: portlistingparse.c,v 1.4 2011/03/18 11:02:17 nanard Exp $ */
|
||||||
|
/* MiniUPnP project
|
||||||
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
|
* (c) 2011 Thomas Bernard
|
||||||
|
* This software is subject to the conditions detailed
|
||||||
|
* in the LICENCE file provided within the distribution */
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "portlistingparse.h"
|
||||||
|
#include "minixml.h"
|
||||||
|
|
||||||
|
/* list of the elements */
|
||||||
|
static const struct {
|
||||||
|
const portMappingElt code;
|
||||||
|
const char * const str;
|
||||||
|
} elements[] = {
|
||||||
|
{ PortMappingEntry, "PortMappingEntry"},
|
||||||
|
{ NewRemoteHost, "NewRemoteHost"},
|
||||||
|
{ NewExternalPort, "NewExternalPort"},
|
||||||
|
{ NewProtocol, "NewProtocol"},
|
||||||
|
{ NewInternalPort, "NewInternalPort"},
|
||||||
|
{ NewInternalClient, "NewInternalClient"},
|
||||||
|
{ NewEnabled, "NewEnabled"},
|
||||||
|
{ NewDescription, "NewDescription"},
|
||||||
|
{ NewLeaseTime, "NewLeaseTime"},
|
||||||
|
{ PortMappingEltNone, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Helper function */
|
||||||
|
static UNSIGNED_INTEGER
|
||||||
|
atoui(const char * p, int l)
|
||||||
|
{
|
||||||
|
UNSIGNED_INTEGER r = 0;
|
||||||
|
while(l > 0 && *p)
|
||||||
|
{
|
||||||
|
if(*p >= '0' && *p <= '9')
|
||||||
|
r = r*10 + (*p - '0');
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
p++;
|
||||||
|
l--;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start element handler */
|
||||||
|
static void
|
||||||
|
startelt(void * d, const char * name, int l)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
|
||||||
|
pdata->curelt = PortMappingEltNone;
|
||||||
|
for(i = 0; elements[i].str; i++)
|
||||||
|
{
|
||||||
|
if(memcmp(name, elements[i].str, l) == 0)
|
||||||
|
{
|
||||||
|
pdata->curelt = elements[i].code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pdata->curelt == PortMappingEntry)
|
||||||
|
{
|
||||||
|
struct PortMapping * pm;
|
||||||
|
pm = calloc(1, sizeof(struct PortMapping));
|
||||||
|
LIST_INSERT_HEAD( &(pdata->head), pm, entries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End element handler */
|
||||||
|
static void
|
||||||
|
endelt(void * d, const char * name, int l)
|
||||||
|
{
|
||||||
|
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
|
||||||
|
pdata->curelt = PortMappingEltNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data handler */
|
||||||
|
static void
|
||||||
|
data(void * d, const char * data, int l)
|
||||||
|
{
|
||||||
|
struct PortMapping * pm;
|
||||||
|
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
|
||||||
|
pm = pdata->head.lh_first;
|
||||||
|
if(!pm)
|
||||||
|
return;
|
||||||
|
if(l > 63)
|
||||||
|
l = 63;
|
||||||
|
switch(pdata->curelt)
|
||||||
|
{
|
||||||
|
case NewRemoteHost:
|
||||||
|
memcpy(pm->remoteHost, data, l);
|
||||||
|
pm->remoteHost[l] = '\0';
|
||||||
|
break;
|
||||||
|
case NewExternalPort:
|
||||||
|
pm->externalPort = (unsigned short)atoui(data, l);
|
||||||
|
break;
|
||||||
|
case NewProtocol:
|
||||||
|
if(l > 3)
|
||||||
|
l = 3;
|
||||||
|
memcpy(pm->protocol, data, l);
|
||||||
|
pm->protocol[l] = '\0';
|
||||||
|
break;
|
||||||
|
case NewInternalPort:
|
||||||
|
pm->internalPort = (unsigned short)atoui(data, l);
|
||||||
|
break;
|
||||||
|
case NewInternalClient:
|
||||||
|
memcpy(pm->internalClient, data, l);
|
||||||
|
pm->internalClient[l] = '\0';
|
||||||
|
break;
|
||||||
|
case NewEnabled:
|
||||||
|
pm->enabled = (unsigned char)atoui(data, l);
|
||||||
|
break;
|
||||||
|
case NewDescription:
|
||||||
|
memcpy(pm->description, data, l);
|
||||||
|
pm->description[l] = '\0';
|
||||||
|
break;
|
||||||
|
case NewLeaseTime:
|
||||||
|
pm->leaseTime = atoui(data, l);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse the PortMappingList XML document for IGD version 2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ParsePortListing(const char * buffer, int bufsize,
|
||||||
|
struct PortMappingParserData * pdata)
|
||||||
|
{
|
||||||
|
struct xmlparser parser;
|
||||||
|
|
||||||
|
memset(pdata, 0, sizeof(struct PortMappingParserData));
|
||||||
|
LIST_INIT(&(pdata->head));
|
||||||
|
/* init xmlparser */
|
||||||
|
parser.xmlstart = buffer;
|
||||||
|
parser.xmlsize = bufsize;
|
||||||
|
parser.data = pdata;
|
||||||
|
parser.starteltfunc = startelt;
|
||||||
|
parser.endeltfunc = endelt;
|
||||||
|
parser.datafunc = data;
|
||||||
|
parser.attfunc = 0;
|
||||||
|
parsexml(&parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FreePortListing(struct PortMappingParserData * pdata)
|
||||||
|
{
|
||||||
|
struct PortMapping * pm;
|
||||||
|
while((pm = pdata->head.lh_first) != NULL)
|
||||||
|
{
|
||||||
|
LIST_REMOVE(pm, entries);
|
||||||
|
free(pm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
71
thirdparty/libportfwd/third-party/miniupnpc-1.6/portlistingparse.h
vendored
Normal file
71
thirdparty/libportfwd/third-party/miniupnpc-1.6/portlistingparse.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/* $Id: portlistingparse.h,v 1.4 2011/02/15 23:03:56 nanard Exp $ */
|
||||||
|
/* MiniUPnP project
|
||||||
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
|
* (c) 2011 Thomas Bernard
|
||||||
|
* This software is subject to the conditions detailed
|
||||||
|
* in the LICENCE file provided within the distribution */
|
||||||
|
#ifndef __PORTLISTINGPARSE_H__
|
||||||
|
#define __PORTLISTINGPARSE_H__
|
||||||
|
|
||||||
|
#include "declspec.h"
|
||||||
|
/* for the definition of UNSIGNED_INTEGER */
|
||||||
|
#include "miniupnpctypes.h"
|
||||||
|
|
||||||
|
#if defined(NO_SYS_QUEUE_H) || defined(WIN32) || defined(__HAIKU__)
|
||||||
|
#include "bsdqueue.h"
|
||||||
|
#else
|
||||||
|
#include <sys/queue.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* sample of PortMappingEntry :
|
||||||
|
<p:PortMappingEntry>
|
||||||
|
<p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
|
||||||
|
<p:NewExternalPort>2345</p:NewExternalPort>
|
||||||
|
<p:NewProtocol>TCP</p:NewProtocol>
|
||||||
|
<p:NewInternalPort>2345</p:NewInternalPort>
|
||||||
|
<p:NewInternalClient>192.168.1.137</p:NewInternalClient>
|
||||||
|
<p:NewEnabled>1</p:NewEnabled>
|
||||||
|
<p:NewDescription>dooom</p:NewDescription>
|
||||||
|
<p:NewLeaseTime>345</p:NewLeaseTime>
|
||||||
|
</p:PortMappingEntry>
|
||||||
|
*/
|
||||||
|
typedef enum { PortMappingEltNone,
|
||||||
|
PortMappingEntry, NewRemoteHost,
|
||||||
|
NewExternalPort, NewProtocol,
|
||||||
|
NewInternalPort, NewInternalClient,
|
||||||
|
NewEnabled, NewDescription,
|
||||||
|
NewLeaseTime } portMappingElt;
|
||||||
|
|
||||||
|
struct PortMapping {
|
||||||
|
LIST_ENTRY(PortMapping) entries;
|
||||||
|
UNSIGNED_INTEGER leaseTime;
|
||||||
|
unsigned short externalPort;
|
||||||
|
unsigned short internalPort;
|
||||||
|
char remoteHost[64];
|
||||||
|
char internalClient[64];
|
||||||
|
char description[64];
|
||||||
|
char protocol[4];
|
||||||
|
unsigned char enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PortMappingParserData {
|
||||||
|
LIST_HEAD(portmappinglisthead, PortMapping) head;
|
||||||
|
portMappingElt curelt;
|
||||||
|
};
|
||||||
|
|
||||||
|
LIBSPEC void
|
||||||
|
ParsePortListing(const char * buffer, int bufsize,
|
||||||
|
struct PortMappingParserData * pdata);
|
||||||
|
|
||||||
|
LIBSPEC void
|
||||||
|
FreePortListing(struct PortMappingParserData * pdata);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
81
thirdparty/libportfwd/third-party/miniupnpc-1.6/receivedata.c
vendored
Normal file
81
thirdparty/libportfwd/third-party/miniupnpc-1.6/receivedata.c
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* $Id: receivedata.c,v 1.1 2011/04/11 08:21:47 nanard Exp $ */
|
||||||
|
/* Project : miniupnp
|
||||||
|
* Author : Thomas Bernard
|
||||||
|
* Copyright (c) 2011 Thomas Bernard
|
||||||
|
* This software is subject to the conditions detailed in the
|
||||||
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#if defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
|
#define socklen_t int
|
||||||
|
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#if !defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
#define MINIUPNPC_IGNORE_EINTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
||||||
|
#else
|
||||||
|
#define PRINT_SOCKET_ERROR(x) perror(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "receivedata.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
receivedata(int socket, char * data, int length, int timeout)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
|
||||||
|
/* using poll */
|
||||||
|
struct pollfd fds[1]; /* for the poll */
|
||||||
|
#ifdef MINIUPNPC_IGNORE_EINTR
|
||||||
|
do {
|
||||||
|
#endif
|
||||||
|
fds[0].fd = socket;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
n = poll(fds, 1, timeout);
|
||||||
|
#ifdef MINIUPNPC_IGNORE_EINTR
|
||||||
|
} while(n < 0 && errno == EINTR);
|
||||||
|
#endif
|
||||||
|
if(n < 0) {
|
||||||
|
PRINT_SOCKET_ERROR("poll");
|
||||||
|
return -1;
|
||||||
|
} else if(n == 0) {
|
||||||
|
/* timeout */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else /* !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||||
|
/* using select under WIN32 and amigaos */
|
||||||
|
fd_set socketSet;
|
||||||
|
TIMEVAL timeval;
|
||||||
|
FD_ZERO(&socketSet);
|
||||||
|
FD_SET(socket, &socketSet);
|
||||||
|
timeval.tv_sec = timeout / 1000;
|
||||||
|
timeval.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
|
||||||
|
if(n < 0) {
|
||||||
|
PRINT_SOCKET_ERROR("select");
|
||||||
|
return -1;
|
||||||
|
} else if(n == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
n = recv(socket, data, length, 0);
|
||||||
|
if(n<0) {
|
||||||
|
PRINT_SOCKET_ERROR("recv");
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
17
thirdparty/libportfwd/third-party/miniupnpc-1.6/receivedata.h
vendored
Normal file
17
thirdparty/libportfwd/third-party/miniupnpc-1.6/receivedata.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* $Id: receivedata.h,v 1.1 2011/04/11 08:21:47 nanard Exp $ */
|
||||||
|
/* Project: miniupnp
|
||||||
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
|
* Author: Thomas Bernard
|
||||||
|
* Copyright (c) 2011 Thomas Bernard
|
||||||
|
* This software is subjects to the conditions detailed
|
||||||
|
* in the LICENCE file provided within this distribution */
|
||||||
|
#ifndef __RECEIVEDATA_H__
|
||||||
|
#define __RECEIVEDATA_H__
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
683
thirdparty/libportfwd/third-party/miniupnpc-1.6/upnpc.c
vendored
Normal file
683
thirdparty/libportfwd/third-party/miniupnpc-1.6/upnpc.c
vendored
Normal file
@@ -0,0 +1,683 @@
|
|||||||
|
/* $Id: upnpc.c,v 1.88 2011/06/17 23:31:01 nanard Exp $ */
|
||||||
|
/* Project : miniupnp
|
||||||
|
* Author : Thomas Bernard
|
||||||
|
* Copyright (c) 2005-2011 Thomas Bernard
|
||||||
|
* This software is subject to the conditions detailed in the
|
||||||
|
* LICENCE file provided in this distribution. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
#include "miniwget.h"
|
||||||
|
#include "miniupnpc.h"
|
||||||
|
#include "upnpcommands.h"
|
||||||
|
#include "upnperrors.h"
|
||||||
|
|
||||||
|
/* protofix() checks if protocol is "UDP" or "TCP"
|
||||||
|
* returns NULL if not */
|
||||||
|
const char * protofix(const char * proto)
|
||||||
|
{
|
||||||
|
static const char proto_tcp[4] = { 'T', 'C', 'P', 0};
|
||||||
|
static const char proto_udp[4] = { 'U', 'D', 'P', 0};
|
||||||
|
int i, b;
|
||||||
|
for(i=0, b=1; i<4; i++)
|
||||||
|
b = b && ( (proto[i] == proto_tcp[i])
|
||||||
|
|| (proto[i] == (proto_tcp[i] | 32)) );
|
||||||
|
if(b)
|
||||||
|
return proto_tcp;
|
||||||
|
for(i=0, b=1; i<4; i++)
|
||||||
|
b = b && ( (proto[i] == proto_udp[i])
|
||||||
|
|| (proto[i] == (proto_udp[i] | 32)) );
|
||||||
|
if(b)
|
||||||
|
return proto_udp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DisplayInfos(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
char externalIPAddress[40];
|
||||||
|
char connectionType[64];
|
||||||
|
char status[64];
|
||||||
|
char lastconnerr[64];
|
||||||
|
unsigned int uptime;
|
||||||
|
unsigned int brUp, brDown;
|
||||||
|
time_t timenow, timestarted;
|
||||||
|
int r;
|
||||||
|
UPNP_GetConnectionTypeInfo(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
connectionType);
|
||||||
|
if(connectionType[0])
|
||||||
|
printf("Connection Type : %s\n", connectionType);
|
||||||
|
else
|
||||||
|
printf("GetConnectionTypeInfo failed.\n");
|
||||||
|
UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
|
||||||
|
status, &uptime, lastconnerr);
|
||||||
|
printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
|
||||||
|
status, uptime, lastconnerr);
|
||||||
|
timenow = time(NULL);
|
||||||
|
timestarted = timenow - uptime;
|
||||||
|
printf(" Time started : %s", ctime(×tarted));
|
||||||
|
UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
|
||||||
|
&brDown, &brUp);
|
||||||
|
printf("MaxBitRateDown : %u bps", brDown);
|
||||||
|
if(brDown >= 1000000) {
|
||||||
|
printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10);
|
||||||
|
} else if(brDown >= 1000) {
|
||||||
|
printf(" (%u Kbps)", brDown / 1000);
|
||||||
|
}
|
||||||
|
printf(" MaxBitRateUp %u bps", brUp);
|
||||||
|
if(brUp >= 1000000) {
|
||||||
|
printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10);
|
||||||
|
} else if(brUp >= 1000) {
|
||||||
|
printf(" (%u Kbps)", brUp / 1000);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
r = UPNP_GetExternalIPAddress(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
externalIPAddress);
|
||||||
|
if(r != UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("GetExternalIPAddress() returned %d\n", r);
|
||||||
|
if(externalIPAddress[0])
|
||||||
|
printf("ExternalIPAddress = %s\n", externalIPAddress);
|
||||||
|
else
|
||||||
|
printf("GetExternalIPAddress failed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetConnectionStatus(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
|
||||||
|
DisplayInfos(urls, data);
|
||||||
|
bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
|
||||||
|
printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListRedirections(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
int i = 0;
|
||||||
|
char index[6];
|
||||||
|
char intClient[40];
|
||||||
|
char intPort[6];
|
||||||
|
char extPort[6];
|
||||||
|
char protocol[4];
|
||||||
|
char desc[80];
|
||||||
|
char enabled[6];
|
||||||
|
char rHost[64];
|
||||||
|
char duration[16];
|
||||||
|
/*unsigned int num=0;
|
||||||
|
UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
|
||||||
|
printf("PortMappingNumberOfEntries : %u\n", num);*/
|
||||||
|
do {
|
||||||
|
snprintf(index, 6, "%d", i);
|
||||||
|
rHost[0] = '\0'; enabled[0] = '\0';
|
||||||
|
duration[0] = '\0'; desc[0] = '\0';
|
||||||
|
extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
|
||||||
|
r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
index,
|
||||||
|
extPort, intClient, intPort,
|
||||||
|
protocol, desc, enabled,
|
||||||
|
rHost, duration);
|
||||||
|
if(r==0)
|
||||||
|
/*
|
||||||
|
printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n"
|
||||||
|
" desc='%s' rHost='%s'\n",
|
||||||
|
i, protocol, extPort, intClient, intPort,
|
||||||
|
enabled, duration,
|
||||||
|
desc, rHost);
|
||||||
|
*/
|
||||||
|
printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",
|
||||||
|
i, protocol, extPort, intClient, intPort,
|
||||||
|
desc, rHost, duration);
|
||||||
|
else
|
||||||
|
printf("GetGenericPortMappingEntry() returned %d (%s)\n",
|
||||||
|
r, strupnperror(r));
|
||||||
|
i++;
|
||||||
|
} while(r==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NewListRedirections(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
int i = 0;
|
||||||
|
struct PortMappingParserData pdata;
|
||||||
|
struct PortMapping * pm;
|
||||||
|
|
||||||
|
memset(&pdata, 0, sizeof(struct PortMappingParserData));
|
||||||
|
r = UPNP_GetListOfPortMappings(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
"0",
|
||||||
|
"65535",
|
||||||
|
"TCP",
|
||||||
|
"1000",
|
||||||
|
&pdata);
|
||||||
|
if(r == UPNPCOMMAND_SUCCESS)
|
||||||
|
{
|
||||||
|
for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
|
||||||
|
{
|
||||||
|
printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
|
||||||
|
i, pm->protocol, pm->externalPort, pm->internalClient,
|
||||||
|
pm->internalPort,
|
||||||
|
pm->description, pm->remoteHost,
|
||||||
|
(unsigned)pm->leaseTime);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
FreePortListing(&pdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("GetListOfPortMappings() returned %d (%s)\n",
|
||||||
|
r, strupnperror(r));
|
||||||
|
}
|
||||||
|
r = UPNP_GetListOfPortMappings(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
"0",
|
||||||
|
"65535",
|
||||||
|
"UDP",
|
||||||
|
"1000",
|
||||||
|
&pdata);
|
||||||
|
if(r == UPNPCOMMAND_SUCCESS)
|
||||||
|
{
|
||||||
|
for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
|
||||||
|
{
|
||||||
|
printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
|
||||||
|
i, pm->protocol, pm->externalPort, pm->internalClient,
|
||||||
|
pm->internalPort,
|
||||||
|
pm->description, pm->remoteHost,
|
||||||
|
(unsigned)pm->leaseTime);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
FreePortListing(&pdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("GetListOfPortMappings() returned %d (%s)\n",
|
||||||
|
r, strupnperror(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test function
|
||||||
|
* 1 - get connection type
|
||||||
|
* 2 - get extenal ip address
|
||||||
|
* 3 - Add port mapping
|
||||||
|
* 4 - get this port mapping from the IGD */
|
||||||
|
static void SetRedirectAndTest(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * iaddr,
|
||||||
|
const char * iport,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto,
|
||||||
|
const char * leaseDuration)
|
||||||
|
{
|
||||||
|
char externalIPAddress[40];
|
||||||
|
char intClient[40];
|
||||||
|
char intPort[6];
|
||||||
|
char duration[16];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if(!iaddr || !iport || !eport || !proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
proto = protofix(proto);
|
||||||
|
if(!proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid protocol\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPNP_GetExternalIPAddress(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
externalIPAddress);
|
||||||
|
if(externalIPAddress[0])
|
||||||
|
printf("ExternalIPAddress = %s\n", externalIPAddress);
|
||||||
|
else
|
||||||
|
printf("GetExternalIPAddress failed.\n");
|
||||||
|
|
||||||
|
r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
|
||||||
|
eport, iport, iaddr, 0, proto, 0, leaseDuration);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
||||||
|
eport, iport, iaddr, r, strupnperror(r));
|
||||||
|
|
||||||
|
r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
|
||||||
|
data->first.servicetype,
|
||||||
|
eport, proto,
|
||||||
|
intClient, intPort, NULL/*desc*/,
|
||||||
|
NULL/*enabled*/, duration);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
|
||||||
|
r, strupnperror(r));
|
||||||
|
|
||||||
|
if(intClient[0]) {
|
||||||
|
printf("InternalIP:Port = %s:%s\n", intClient, intPort);
|
||||||
|
printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n",
|
||||||
|
externalIPAddress, eport, proto, intClient, intPort, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
RemoveRedirect(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data,
|
||||||
|
const char * eport,
|
||||||
|
const char * proto)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if(!proto || !eport)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
proto = protofix(proto);
|
||||||
|
if(!proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "protocol invalid\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0);
|
||||||
|
printf("UPNP_DeletePortMapping() returned : %d\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
|
||||||
|
static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
|
||||||
|
{
|
||||||
|
unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
|
||||||
|
int firewallEnabled = 0, inboundPinholeAllowed = 0;
|
||||||
|
|
||||||
|
UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed);
|
||||||
|
printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed);
|
||||||
|
printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No");
|
||||||
|
|
||||||
|
bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
|
||||||
|
printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
|
||||||
|
printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test function
|
||||||
|
* 1 - Add pinhole
|
||||||
|
* 2 - Check if pinhole is working from the IGD side */
|
||||||
|
static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data,
|
||||||
|
const char * remoteaddr, const char * eport,
|
||||||
|
const char * intaddr, const char * iport,
|
||||||
|
const char * proto, const char * lease_time)
|
||||||
|
{
|
||||||
|
char uniqueID[8];
|
||||||
|
//int isWorking = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*proto = protofix(proto);
|
||||||
|
if(!proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid protocol\n");
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
|
||||||
|
intaddr, iport, remoteaddr, eport, r, strupnperror(r));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", intaddr, iport, remoteaddr, eport, uniqueID);
|
||||||
|
/*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
|
||||||
|
printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test function
|
||||||
|
* 1 - Check if pinhole is working from the IGD side
|
||||||
|
* 2 - Update pinhole */
|
||||||
|
static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data,
|
||||||
|
const char * uniqueID, const char * lease_time)
|
||||||
|
{
|
||||||
|
int isWorking = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if(!uniqueID || !lease_time)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
|
||||||
|
printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
|
||||||
|
if(isWorking || r==709)
|
||||||
|
{
|
||||||
|
r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time);
|
||||||
|
printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test function
|
||||||
|
* Get pinhole timeout
|
||||||
|
*/
|
||||||
|
static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data,
|
||||||
|
const char * remoteaddr, const char * eport,
|
||||||
|
const char * intaddr, const char * iport,
|
||||||
|
const char * proto)
|
||||||
|
{
|
||||||
|
int timeout = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if(!intaddr || !remoteaddr || !iport || !eport || !proto)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
|
||||||
|
intaddr, iport, remoteaddr, eport, r, strupnperror(r));
|
||||||
|
else
|
||||||
|
printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GetPinholePackets(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data, const char * uniqueID)
|
||||||
|
{
|
||||||
|
int r, pinholePackets = 0;
|
||||||
|
if(!uniqueID)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r));
|
||||||
|
else
|
||||||
|
printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CheckPinhole(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data, const char * uniqueID)
|
||||||
|
{
|
||||||
|
int r, isWorking = 0;
|
||||||
|
if(!uniqueID)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
|
||||||
|
if(r!=UPNPCOMMAND_SUCCESS)
|
||||||
|
printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
|
||||||
|
else
|
||||||
|
printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
RemovePinhole(struct UPNPUrls * urls,
|
||||||
|
struct IGDdatas * data, const char * uniqueID)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if(!uniqueID)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid arguments\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID);
|
||||||
|
printf("UPNP_DeletePinhole() returned : %d\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sample upnp client program */
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
char command = 0;
|
||||||
|
char ** commandargv = 0;
|
||||||
|
int commandargc = 0;
|
||||||
|
struct UPNPDev * devlist = 0;
|
||||||
|
char lanaddr[64]; /* my ip address on the LAN */
|
||||||
|
int i;
|
||||||
|
const char * rootdescurl = 0;
|
||||||
|
const char * multicastif = 0;
|
||||||
|
const char * minissdpdpath = 0;
|
||||||
|
int retcode = 0;
|
||||||
|
int error = 0;
|
||||||
|
int ipv6 = 0;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WSADATA wsaData;
|
||||||
|
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||||
|
if(nResult != NO_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WSAStartup() failed.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
printf("upnpc : miniupnpc library test client. (c) 2006-2011 Thomas Bernard\n");
|
||||||
|
printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
|
||||||
|
"for more information.\n");
|
||||||
|
/* command line processing */
|
||||||
|
for(i=1; i<argc; i++)
|
||||||
|
{
|
||||||
|
if(argv[i][0] == '-')
|
||||||
|
{
|
||||||
|
if(argv[i][1] == 'u')
|
||||||
|
rootdescurl = argv[++i];
|
||||||
|
else if(argv[i][1] == 'm')
|
||||||
|
multicastif = argv[++i];
|
||||||
|
else if(argv[i][1] == 'p')
|
||||||
|
minissdpdpath = argv[++i];
|
||||||
|
else if(argv[i][1] == '6')
|
||||||
|
ipv6 = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
command = argv[i][1];
|
||||||
|
i++;
|
||||||
|
commandargv = argv + i;
|
||||||
|
commandargc = argc - i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "option '%s' invalid\n", argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!command || (command == 'a' && commandargc<4)
|
||||||
|
|| (command == 'd' && argc<2)
|
||||||
|
|| (command == 'r' && argc<2)
|
||||||
|
|| (command == 'A' && commandargc<6)
|
||||||
|
|| (command == 'U' && commandargc<2)
|
||||||
|
|| (command == 'D' && commandargc<1))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings, IGD v2)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]);
|
||||||
|
fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]);
|
||||||
|
fprintf(stderr, "\nprotocol is UDP or TCP\n");
|
||||||
|
fprintf(stderr, "Options:\n");
|
||||||
|
fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n");
|
||||||
|
fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n");
|
||||||
|
fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v6) to use for sending SSDP multicast packets.\n");
|
||||||
|
fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rootdescurl
|
||||||
|
|| (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
|
||||||
|
0/*sameport*/, ipv6, &error)))
|
||||||
|
{
|
||||||
|
struct UPNPDev * device;
|
||||||
|
struct UPNPUrls urls;
|
||||||
|
struct IGDdatas data;
|
||||||
|
if(devlist)
|
||||||
|
{
|
||||||
|
printf("List of UPNP devices found on the network :\n");
|
||||||
|
for(device = devlist; device; device = device->pNext)
|
||||||
|
{
|
||||||
|
printf(" desc: %s\n st: %s\n\n",
|
||||||
|
device->descURL, device->st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("upnpDiscover() error code=%d\n", error);
|
||||||
|
}
|
||||||
|
i = 1;
|
||||||
|
if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
|
||||||
|
|| (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
|
||||||
|
{
|
||||||
|
switch(i) {
|
||||||
|
case 1:
|
||||||
|
printf("Found valid IGD : %s\n", urls.controlURL);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
|
||||||
|
printf("Trying to continue anyway\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
|
||||||
|
printf("Trying to continue anyway\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Found device (igd ?) : %s\n", urls.controlURL);
|
||||||
|
printf("Trying to continue anyway\n");
|
||||||
|
}
|
||||||
|
printf("Local LAN ip address : %s\n", lanaddr);
|
||||||
|
#if 0
|
||||||
|
printf("getting \"%s\"\n", urls.ipcondescURL);
|
||||||
|
descXML = miniwget(urls.ipcondescURL, &descXMLsize);
|
||||||
|
if(descXML)
|
||||||
|
{
|
||||||
|
/*fwrite(descXML, 1, descXMLsize, stdout);*/
|
||||||
|
free(descXML); descXML = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(command)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
DisplayInfos(&urls, &data);
|
||||||
|
ListRedirections(&urls, &data);
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
NewListRedirections(&urls, &data);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
SetRedirectAndTest(&urls, &data,
|
||||||
|
commandargv[0], commandargv[1],
|
||||||
|
commandargv[2], commandargv[3],
|
||||||
|
(commandargc > 4)?commandargv[4]:"0");
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
for(i=0; i<commandargc; i+=2)
|
||||||
|
{
|
||||||
|
RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
GetConnectionStatus(&urls, &data);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
for(i=0; i<commandargc; i+=2)
|
||||||
|
{
|
||||||
|
/*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
|
||||||
|
SetRedirectAndTest(&urls, &data,
|
||||||
|
lanaddr, commandargv[i],
|
||||||
|
commandargv[i], commandargv[i+1], "0");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
SetPinholeAndTest(&urls, &data,
|
||||||
|
commandargv[0], commandargv[1],
|
||||||
|
commandargv[2], commandargv[3],
|
||||||
|
commandargv[4], commandargv[5]);
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
GetPinholeAndUpdate(&urls, &data,
|
||||||
|
commandargv[0], commandargv[1]);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
for(i=0; i<commandargc; i++)
|
||||||
|
{
|
||||||
|
CheckPinhole(&urls, &data, commandargv[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
for(i=0; i<commandargc; i++)
|
||||||
|
{
|
||||||
|
GetPinholePackets(&urls, &data, commandargv[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
for(i=0; i<commandargc; i++)
|
||||||
|
{
|
||||||
|
RemovePinhole(&urls, &data, commandargv[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
GetFirewallStatus(&urls, &data);
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
GetPinholeOutboundTimeout(&urls, &data,
|
||||||
|
commandargv[0], commandargv[1],
|
||||||
|
commandargv[2], commandargv[3],
|
||||||
|
commandargv[4]);
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
printf("Presentation URL found:\n");
|
||||||
|
printf(" %s\n", data.presentationurl);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown switch -%c\n", command);
|
||||||
|
retcode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeUPNPUrls(&urls);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
|
||||||
|
retcode = 1;
|
||||||
|
}
|
||||||
|
freeUPNPDevlist(devlist); devlist = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No IGD UPnP Device found on the network !\n");
|
||||||
|
retcode = 1;
|
||||||
|
}
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
1097
thirdparty/libportfwd/third-party/miniupnpc-1.6/upnpcommands.c
vendored
Normal file
1097
thirdparty/libportfwd/third-party/miniupnpc-1.6/upnpcommands.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,16 @@
|
|||||||
/* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
|
/* $Id: upnpcommands.h,v 1.23 2011/04/11 09:14:00 nanard Exp $ */
|
||||||
/* Miniupnp project : http://miniupnp.free.fr/
|
/* Miniupnp project : http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005-2010 Thomas Bernard
|
* Copyright (c) 2005-2011 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed in the
|
* This software is subject to the conditions detailed in the
|
||||||
* LICENCE file provided within this distribution */
|
* LICENCE file provided within this distribution */
|
||||||
#ifndef __UPNPCOMMANDS_H__
|
#ifndef __UPNPCOMMANDS_H__
|
||||||
#define __UPNPCOMMANDS_H__
|
#define __UPNPCOMMANDS_H__
|
||||||
|
|
||||||
#include "upnpreplyparse.h"
|
#include "upnpreplyparse.h"
|
||||||
|
#include "portlistingparse.h"
|
||||||
#include "declspec.h"
|
#include "declspec.h"
|
||||||
|
#include "miniupnpctypes.h"
|
||||||
|
|
||||||
/* MiniUPnPc return codes : */
|
/* MiniUPnPc return codes : */
|
||||||
#define UPNPCOMMAND_SUCCESS (0)
|
#define UPNPCOMMAND_SUCCESS (0)
|
||||||
@@ -20,14 +22,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
|
|
||||||
#define UNSIGNED_INTEGER unsigned long long
|
|
||||||
#define STRTOUI strtoull
|
|
||||||
#else
|
|
||||||
#define UNSIGNED_INTEGER unsigned int
|
|
||||||
#define STRTOUI strtoul
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LIBSPEC UNSIGNED_INTEGER
|
LIBSPEC UNSIGNED_INTEGER
|
||||||
UPNP_GetTotalBytesSent(const char * controlURL,
|
UPNP_GetTotalBytesSent(const char * controlURL,
|
||||||
const char * servicetype);
|
const char * servicetype);
|
||||||
@@ -126,7 +120,8 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
|||||||
const char * inClient,
|
const char * inClient,
|
||||||
const char * desc,
|
const char * desc,
|
||||||
const char * proto,
|
const char * proto,
|
||||||
const char * remoteHost);
|
const char * remoteHost,
|
||||||
|
const char * leaseDuration);
|
||||||
|
|
||||||
/* UPNP_DeletePortMapping()
|
/* UPNP_DeletePortMapping()
|
||||||
* Use same argument values as what was used for AddPortMapping().
|
* Use same argument values as what was used for AddPortMapping().
|
||||||
@@ -146,11 +141,20 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
|||||||
/* UPNP_GetPortMappingNumberOfEntries()
|
/* UPNP_GetPortMappingNumberOfEntries()
|
||||||
* not supported by all routers */
|
* not supported by all routers */
|
||||||
LIBSPEC int
|
LIBSPEC int
|
||||||
UPNP_GetPortMappingNumberOfEntries(const char* controlURL, const char* servicetype, unsigned int * num);
|
UPNP_GetPortMappingNumberOfEntries(const char* controlURL,
|
||||||
|
const char* servicetype,
|
||||||
|
unsigned int * num);
|
||||||
|
|
||||||
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
|
/* UPNP_GetSpecificPortMappingEntry()
|
||||||
* the result is returned in the intClient and intPort strings
|
* retrieves an existing port mapping
|
||||||
* please provide 16 and 6 bytes of data
|
* params :
|
||||||
|
* in extPort
|
||||||
|
* in proto
|
||||||
|
* out intClient (16 bytes)
|
||||||
|
* out intPort (6 bytes)
|
||||||
|
* out desc (80 bytes)
|
||||||
|
* out enabled (4 bytes)
|
||||||
|
* out leaseDuration (16 bytes)
|
||||||
*
|
*
|
||||||
* return value :
|
* return value :
|
||||||
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
||||||
@@ -161,9 +165,22 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
|||||||
const char * extPort,
|
const char * extPort,
|
||||||
const char * proto,
|
const char * proto,
|
||||||
char * intClient,
|
char * intClient,
|
||||||
char * intPort);
|
char * intPort,
|
||||||
|
char * desc,
|
||||||
|
char * enabled,
|
||||||
|
char * leaseDuration);
|
||||||
|
|
||||||
/* UPNP_GetGenericPortMappingEntry()
|
/* UPNP_GetGenericPortMappingEntry()
|
||||||
|
* params :
|
||||||
|
* in index
|
||||||
|
* out extPort (6 bytes)
|
||||||
|
* out intClient (16 bytes)
|
||||||
|
* out intPort (6 bytes)
|
||||||
|
* out protocol (4 bytes)
|
||||||
|
* out desc (80 bytes)
|
||||||
|
* out enabled (4 bytes)
|
||||||
|
* out rHost (64 bytes)
|
||||||
|
* out duration (16 bytes)
|
||||||
*
|
*
|
||||||
* return value :
|
* return value :
|
||||||
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
|
||||||
@@ -186,6 +203,66 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
|||||||
char * rHost,
|
char * rHost,
|
||||||
char * duration);
|
char * duration);
|
||||||
|
|
||||||
|
/* UPNP_GetListOfPortMappings() Available in IGD v2
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Possible UPNP Error codes :
|
||||||
|
* 606 Action not Authorized
|
||||||
|
* 730 PortMappingNotFound - no port mapping is found in the specified range.
|
||||||
|
* 733 InconsistantParameters - NewStartPort and NewEndPort values are not
|
||||||
|
* consistent.
|
||||||
|
*/
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_GetListOfPortMappings(const char * controlURL,
|
||||||
|
const char * servicetype,
|
||||||
|
const char * startPort,
|
||||||
|
const char * endPort,
|
||||||
|
const char * protocol,
|
||||||
|
const char * numberOfPorts,
|
||||||
|
struct PortMappingParserData * data);
|
||||||
|
|
||||||
|
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_GetFirewallStatus(const char * controlURL,
|
||||||
|
const char * servicetype,
|
||||||
|
int * firewallEnabled,
|
||||||
|
int * inboundPinholeAllowed);
|
||||||
|
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
|
||||||
|
const char * remoteHost,
|
||||||
|
const char * remotePort,
|
||||||
|
const char * intClient,
|
||||||
|
const char * intPort,
|
||||||
|
const char * proto,
|
||||||
|
int * opTimeout);
|
||||||
|
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_AddPinhole(const char * controlURL, const char * servicetype,
|
||||||
|
const char * remoteHost,
|
||||||
|
const char * remotePort,
|
||||||
|
const char * intClient,
|
||||||
|
const char * intPort,
|
||||||
|
const char * proto,
|
||||||
|
const char * leaseTime,
|
||||||
|
char * uniqueID);
|
||||||
|
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
|
||||||
|
const char * uniqueID,
|
||||||
|
const char * leaseTime);
|
||||||
|
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);
|
||||||
|
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
|
||||||
|
const char * uniqueID, int * isWorking);
|
||||||
|
|
||||||
|
LIBSPEC int
|
||||||
|
UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
|
||||||
|
const char * uniqueID, int * packets);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: upnperrors.c,v 1.3 2008/04/27 17:21:51 nanard Exp $ */
|
/* $Id: upnperrors.c,v 1.5 2011/04/10 11:19:36 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
* copyright (c) 2007 Thomas Bernard
|
* copyright (c) 2007 Thomas Bernard
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "upnperrors.h"
|
#include "upnperrors.h"
|
||||||
#include "upnpcommands.h"
|
#include "upnpcommands.h"
|
||||||
|
#include "miniupnpc.h"
|
||||||
|
|
||||||
const char * strupnperror(int err)
|
const char * strupnperror(int err)
|
||||||
{
|
{
|
||||||
@@ -23,6 +24,12 @@ const char * strupnperror(int err)
|
|||||||
case UPNPCOMMAND_INVALID_ARGS:
|
case UPNPCOMMAND_INVALID_ARGS:
|
||||||
s = "Miniupnpc Invalid Arguments";
|
s = "Miniupnpc Invalid Arguments";
|
||||||
break;
|
break;
|
||||||
|
case UPNPDISCOVER_SOCKET_ERROR:
|
||||||
|
s = "Miniupnpc Socket error";
|
||||||
|
break;
|
||||||
|
case UPNPDISCOVER_MEMORY_ERROR:
|
||||||
|
s = "Miniupnpc Memory allocation error";
|
||||||
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
s = "Invalid Action";
|
s = "Invalid Action";
|
||||||
break;
|
break;
|
||||||
@@ -32,6 +39,36 @@ const char * strupnperror(int err)
|
|||||||
case 501:
|
case 501:
|
||||||
s = "Action Failed";
|
s = "Action Failed";
|
||||||
break;
|
break;
|
||||||
|
case 606:
|
||||||
|
s = "Action not authorized";
|
||||||
|
break;
|
||||||
|
case 701:
|
||||||
|
s = "PinholeSpaceExhausted";
|
||||||
|
break;
|
||||||
|
case 702:
|
||||||
|
s = "FirewallDisabled";
|
||||||
|
break;
|
||||||
|
case 703:
|
||||||
|
s = "InboundPinholeNotAllowed";
|
||||||
|
break;
|
||||||
|
case 704:
|
||||||
|
s = "NoSuchEntry";
|
||||||
|
break;
|
||||||
|
case 705:
|
||||||
|
s = "ProtocolNotSupported";
|
||||||
|
break;
|
||||||
|
case 706:
|
||||||
|
s = "InternalPortWildcardingNotAllowed";
|
||||||
|
break;
|
||||||
|
case 707:
|
||||||
|
s = "ProtocolWildcardingNotAllowed";
|
||||||
|
break;
|
||||||
|
case 708:
|
||||||
|
s = "WildcardNotPermittedInSrcIP";
|
||||||
|
break;
|
||||||
|
case 709:
|
||||||
|
s = "NoPacketSent";
|
||||||
|
break;
|
||||||
case 713:
|
case 713:
|
||||||
s = "SpecifiedArrayIndexInvalid";
|
s = "SpecifiedArrayIndexInvalid";
|
||||||
break;
|
break;
|
@@ -1,7 +1,7 @@
|
|||||||
/* $Id: upnpreplyparse.c,v 1.10 2008/02/21 13:05:27 nanard Exp $ */
|
/* $Id: upnpreplyparse.c,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
|
||||||
/* MiniUPnP project
|
/* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* (c) 2006 Thomas Bernard
|
* (c) 2006-2011 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
@@ -27,22 +27,41 @@ NameValueParserGetData(void * d, const char * datas, int l)
|
|||||||
{
|
{
|
||||||
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
||||||
struct NameValue * nv;
|
struct NameValue * nv;
|
||||||
nv = malloc(sizeof(struct NameValue));
|
if(strcmp(data->curelt, "NewPortListing") == 0)
|
||||||
if(l>63)
|
{
|
||||||
l = 63;
|
/* specific case for NewPortListing which is a XML Document */
|
||||||
strncpy(nv->name, data->curelt, 64);
|
data->portListing = malloc(l + 1);
|
||||||
nv->name[63] = '\0';
|
if(!data->portListing)
|
||||||
memcpy(nv->value, datas, l);
|
{
|
||||||
nv->value[l] = '\0';
|
/* malloc error */
|
||||||
LIST_INSERT_HEAD( &(data->head), nv, entries);
|
return;
|
||||||
|
}
|
||||||
|
memcpy(data->portListing, datas, l);
|
||||||
|
data->portListing[l] = '\0';
|
||||||
|
data->portListingLength = l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* standard case. Limited to 63 chars strings */
|
||||||
|
nv = malloc(sizeof(struct NameValue));
|
||||||
|
if(l>63)
|
||||||
|
l = 63;
|
||||||
|
strncpy(nv->name, data->curelt, 64);
|
||||||
|
nv->name[63] = '\0';
|
||||||
|
memcpy(nv->value, datas, l);
|
||||||
|
nv->value[l] = '\0';
|
||||||
|
LIST_INSERT_HEAD( &(data->head), nv, entries);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ParseNameValue(const char * buffer, int bufsize,
|
ParseNameValue(const char * buffer, int bufsize,
|
||||||
struct NameValueParserData * data)
|
struct NameValueParserData * data)
|
||||||
{
|
{
|
||||||
struct xmlparser parser;
|
struct xmlparser parser;
|
||||||
LIST_INIT(&(data->head));
|
LIST_INIT(&(data->head));
|
||||||
|
data->portListing = NULL;
|
||||||
|
data->portListingLength = 0;
|
||||||
/* init xmlparser object */
|
/* init xmlparser object */
|
||||||
parser.xmlstart = buffer;
|
parser.xmlstart = buffer;
|
||||||
parser.xmlsize = bufsize;
|
parser.xmlsize = bufsize;
|
||||||
@@ -58,6 +77,12 @@ void
|
|||||||
ClearNameValueList(struct NameValueParserData * pdata)
|
ClearNameValueList(struct NameValueParserData * pdata)
|
||||||
{
|
{
|
||||||
struct NameValue * nv;
|
struct NameValue * nv;
|
||||||
|
if(pdata->portListing)
|
||||||
|
{
|
||||||
|
free(pdata->portListing);
|
||||||
|
pdata->portListing = NULL;
|
||||||
|
pdata->portListingLength = 0;
|
||||||
|
}
|
||||||
while((nv = pdata->head.lh_first) != NULL)
|
while((nv = pdata->head.lh_first) != NULL)
|
||||||
{
|
{
|
||||||
LIST_REMOVE(nv, entries);
|
LIST_REMOVE(nv, entries);
|
@@ -1,7 +1,7 @@
|
|||||||
/* $Id: upnpreplyparse.h,v 1.10 2009/07/09 16:01:50 nanard Exp $ */
|
/* $Id: upnpreplyparse.h,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
|
||||||
/* MiniUPnP project
|
/* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* (c) 2006-2009 Thomas Bernard
|
* (c) 2006-2011 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
@@ -27,6 +27,8 @@ struct NameValue {
|
|||||||
struct NameValueParserData {
|
struct NameValueParserData {
|
||||||
LIST_HEAD(listhead, NameValue) head;
|
LIST_HEAD(listhead, NameValue) head;
|
||||||
char curelt[64];
|
char curelt[64];
|
||||||
|
char * portListing;
|
||||||
|
int portListingLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ParseNameValue() */
|
/* ParseNameValue() */
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: wingenminiupnpcstrings.c,v 1.1 2009/12/10 18:46:15 nanard Exp $ */
|
/* $Id: wingenminiupnpcstrings.c,v 1.2 2011/01/11 15:31:13 nanard Exp $ */
|
||||||
/* Project: miniupnp
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
@@ -18,6 +18,7 @@ int main(int argc, char * * argv) {
|
|||||||
FILE * fin;
|
FILE * fin;
|
||||||
FILE * fout;
|
FILE * fout;
|
||||||
int n;
|
int n;
|
||||||
|
char miniupnpcVersion[32];
|
||||||
/* dwMajorVersion :
|
/* dwMajorVersion :
|
||||||
The major version number of the operating system. For more information, see Remarks.
|
The major version number of the operating system. For more information, see Remarks.
|
||||||
dwMinorVersion :
|
dwMinorVersion :
|
||||||
@@ -40,6 +41,15 @@ int main(int argc, char * * argv) {
|
|||||||
osvi.dwMajorVersion, osvi.dwMinorVersion,
|
osvi.dwMajorVersion, osvi.dwMinorVersion,
|
||||||
osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion));
|
osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion));
|
||||||
|
|
||||||
|
fin = fopen("VERSION", "r");
|
||||||
|
fgets(miniupnpcVersion, sizeof(miniupnpcVersion), fin);
|
||||||
|
fclose(fin);
|
||||||
|
for(n = 0; n < sizeof(miniupnpcVersion); n++) {
|
||||||
|
if(miniupnpcVersion[n] < ' ')
|
||||||
|
miniupnpcVersion[n] = '\0';
|
||||||
|
}
|
||||||
|
printf("MiniUPnPc version %s\n", miniupnpcVersion);
|
||||||
|
|
||||||
if(argc >= 3) {
|
if(argc >= 3) {
|
||||||
fin = fopen(argv[1], "r");
|
fin = fopen(argv[1], "r");
|
||||||
if(!fin) {
|
if(!fin) {
|
||||||
@@ -56,6 +66,9 @@ int main(int argc, char * * argv) {
|
|||||||
if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) {
|
if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) {
|
||||||
sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n",
|
sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n",
|
||||||
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
|
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
|
||||||
|
} else if(0 == memcmp(buffer, "#define MINIUPNPC_VERSION_STRING \"version\"", 42)) {
|
||||||
|
sprintf(buffer, "#define MINIUPNPC_VERSION_STRING \"%s\"\n",
|
||||||
|
miniupnpcVersion);
|
||||||
}
|
}
|
||||||
/*fputs(buffer, stdout);*/
|
/*fputs(buffer, stdout);*/
|
||||||
fputs(buffer, fout);
|
fputs(buffer, fout);
|
Reference in New Issue
Block a user