- upgrade embedded miniupnpc to 1.7 (fixes build)

This commit is contained in:
Mark Vejvoda 2012-12-27 18:59:38 +00:00
parent 7fdd70402d
commit 4c94cedb85
33 changed files with 701 additions and 338 deletions

View File

@ -296,6 +296,11 @@ option(ENABLE_FRIBIDI "Enable FriBIDi support" ON)
if(NOT MINIUPNP_FOUND)
MESSAGE(STATUS "*** Using EMBEDDED miniupnpc since dev system does not have it... MINIUPNP_FOUND [${MINIUPNP_FOUND}]")
if (NOT WIN32)
add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
add_definitions (-D_BSD_SOURCE -D_POSIX_C_SOURCE=1)
endif()
SET(DIRS_WITH_SRC ${DIRS_WITH_SRC} platform/miniupnpc)
else()
MESSAGE(STATUS "*** Using SHARED miniupnpc found in [${MINIUPNP_INCLUDE_DIR}] MINIUPNP_FOUND [${MINIUPNP_FOUND}] MINIUPNP_LIBRARY [${MINIUPNP_LIBRARY}]")

View File

@ -36,7 +36,7 @@
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
*
@ -95,7 +95,7 @@
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
@ -107,7 +107,7 @@ struct name { \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
@ -322,8 +322,8 @@ struct { \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
/*
* tail queue access methods
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
@ -430,7 +430,7 @@ struct { \
}
/*
* Circular queue access methods
* Circular queue access methods
*/
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)

View File

@ -1,7 +1,7 @@
/* $Id: codelength.h,v 1.1 2008/10/06 22:04:06 nanard Exp $ */
/* $Id: codelength.h,v 1.3 2011/07/30 13:10:05 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2008 Thomas Bernard
* copyright (c) 2005-2011 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#ifndef __CODELENGTH_H__
@ -12,7 +12,14 @@
* following byte is part of the code */
#define DECODELENGTH(n, p) n = 0; \
do { n = (n << 7) | (*p & 0x7f); } \
while(*(p++)&0x80);
while((*(p++)&0x80) && (n<(1<<25)));
#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
n = 0; \
do { \
if((p) >= (p_limit)) break; \
n = (n << 7) | (*(p) & 0x7f); \
} while((*((p)++)&0x80) && (n<(1<<25)));
#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
if(n>=2097152) *(p++) = (n >> 21) | 0x80; \

View File

@ -1,8 +1,8 @@
/* $Id: connecthostport.h,v 1.1 2010/04/04 23:21:03 nanard Exp $ */
/* $Id: connecthostport.h,v 1.2 2012/06/23 22:32:33 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2010 Thomas Bernard
* Copyright (c) 2010-2012 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __CONNECTHOSTPORT_H__
@ -11,7 +11,8 @@
/* connecthostport()
* return a socket connected (TCP) to the host and port
* or -1 in case of error */
int connecthostport(const char * host, unsigned short port);
int connecthostport(const char * host, unsigned short port,
unsigned int scope_id);
#endif

View File

@ -1,7 +1,7 @@
#ifndef __DECLSPEC_H__
#define __DECLSPEC_H__
#if defined(WIN32) && !defined(STATICLIB)
#if defined(_WIN32) && !defined(STATICLIB)
#ifdef MINIUPNP_EXPORTS
#define LIBSPEC __declspec(dllexport)
#else

View File

@ -1,17 +1,13 @@
/* $Id: miniupnpc.h,v 1.23 2011/04/11 08:21:46 nanard Exp $ */
/* $Id: miniupnpc.h,v 1.30 2012/06/28 18:52:12 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
* Copyright (c) 2005-2012 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __MINIUPNPC_H__
#define __MINIUPNPC_H__
//#define MEGAGLEST_EMBEDDED_MINIUPNPC
//#define MINIUPNPC_VERSION_PRE1_5
//#define MINIUPNPC_VERSION_PRE1_6
#include "declspec.h"
#include "igd_desc_parse.h"
@ -21,6 +17,10 @@
#define UPNPDISCOVER_SOCKET_ERROR (-101)
#define UPNPDISCOVER_MEMORY_ERROR (-102)
/* versions : */
#define MINIUPNPC_VERSION "1.7.20120830"
#define MINIUPNPC_API_VERSION 9
#ifdef __cplusplus
extern "C" {
#endif
@ -37,6 +37,7 @@ struct UPNPDev {
struct UPNPDev * pNext;
char * descURL;
char * st;
unsigned int scope_id;
char buffer[2];
};
@ -78,6 +79,7 @@ struct UPNPUrls {
char * ipcondescURL;
char * controlURL_CIF;
char * controlURL_6FC;
char * rootdescURL;
};
/* UPNP_GetValidIGD() :
@ -109,9 +111,12 @@ UPNP_GetIGDFromUrl(const char * rootdescurl,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen);
LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);
LIBSPEC void
GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
const char *, unsigned int);
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
LIBSPEC void
FreeUPNPUrls(struct UPNPUrls *);
/* return 0 or 1 */
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);

View File

@ -1,7 +1,7 @@
/* $Id: miniwget.h,v 1.6 2010/12/09 16:11:33 nanard Exp $ */
/* $Id: miniwget.h,v 1.7 2012/06/23 22:35:59 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* Copyright (c) 2005-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
@ -16,11 +16,11 @@ extern "C" {
LIBSPEC void * getHTTPResponse(int s, int * size);
LIBSPEC void * miniwget(const char *, int *);
LIBSPEC void * miniwget(const char *, int *, unsigned int);
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int);
int parseURL(const char *, char *, unsigned short *, char * *);
int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
#ifdef __cplusplus
}

View File

@ -1,7 +1,7 @@
/* $Id: portlistingparse.h,v 1.4 2011/02/15 23:03:56 nanard Exp $ */
/* $Id: portlistingparse.h,v 1.6 2012/03/05 19:42:47 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2011 Thomas Bernard
* (c) 2011-2012 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef __PORTLISTINGPARSE_H__
@ -11,7 +11,7 @@
/* for the definition of UNSIGNED_INTEGER */
#include "miniupnpctypes.h"
#if defined(NO_SYS_QUEUE_H) || defined(WIN32) || defined(__HAIKU__)
#if defined(NO_SYS_QUEUE_H) || defined(_WIN32) || defined(__HAIKU__)
#include "bsdqueue.h"
#else
#include <sys/queue.h>
@ -37,7 +37,7 @@ typedef enum { PortMappingEltNone,
PortMappingEntry, NewRemoteHost,
NewExternalPort, NewProtocol,
NewInternalPort, NewInternalClient,
NewEnabled, NewDescription,
NewEnabled, NewDescription,
NewLeaseTime } portMappingElt;
struct PortMapping {

View File

@ -1,17 +1,19 @@
/* $Id: receivedata.h,v 1.1 2011/04/11 08:21:47 nanard Exp $ */
/* $Id: receivedata.h,v 1.3 2012/06/23 22:34:47 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2011 Thomas Bernard
* Copyright (c) 2011-2012 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __RECEIVEDATA_H__
#define __RECEIVEDATA_H__
/* Reads data from the specified socket.
* Returns the number of bytes read if successful, zero if no bytes were
/* 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);
int receivedata(int socket,
char * data, int length,
int timeout, unsigned int * scope_id);
#endif

View File

@ -1,4 +1,4 @@
/* $Id: upnpcommands.h,v 1.23 2011/04/11 09:14:00 nanard Exp $ */
/* $Id: upnpcommands.h,v 1.24 2012/03/05 19:42:47 nanard Exp $ */
/* Miniupnp project : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
@ -62,12 +62,12 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available
* at least 16 bytes must be available
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
*
*
* possible UPnP Errors :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control. */
@ -95,7 +95,7 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
*
*
* List of possible UPnP errors for AddPortMapping :
* errorCode errorDescription (short) - Description (long)
* 402 Invalid Args - See UPnP Device Architecture section on Control.
@ -106,7 +106,7 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
* 718 ConflictInMappingEntry - The port mapping entry specified conflicts
* with a mapping assigned previously to another client
* 724 SamePortValuesRequired - Internal and External port values
* must be the same
* must be the same
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
* permanent lease times on port mappings
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
@ -221,11 +221,11 @@ UPNP_GetListOfPortMappings(const char * controlURL,
const char * numberOfPorts,
struct PortMappingParserData * data);
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
LIBSPEC int
UPNP_GetFirewallStatus(const char * controlURL,
const char * servicetype,
int * firewallEnabled,
int * firewallEnabled,
int * inboundPinholeAllowed);
LIBSPEC int

View File

@ -1,4 +1,4 @@
/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */
/* $Id: upnperrors.h,v 1.3 2012/03/05 19:42:47 nanard Exp $ */
/* (c) 2007 Thomas Bernard
* All rights reserved.
* MiniUPnP Project.
@ -15,7 +15,7 @@ extern "C" {
#endif
/* strupnperror()
* Return a string description of the UPnP error code
* Return a string description of the UPnP error code
* or NULL for undefinded errors */
LIBSPEC const char * strupnperror(int err);

View File

@ -1,14 +1,14 @@
/* $Id: upnpreplyparse.h,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
/* $Id: upnpreplyparse.h,v 1.13 2012/03/05 19:42:48 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2011 Thomas Bernard
* (c) 2006-2012 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef __UPNPREPLYPARSE_H__
#define __UPNPREPLYPARSE_H__
#if defined(NO_SYS_QUEUE_H) || defined(WIN32) || defined(__HAIKU__)
#if defined(NO_SYS_QUEUE_H) || defined(_WIN32) || defined(__HAIKU__)
#include "bsdqueue.h"
#else
#include <sys/queue.h>

View File

@ -1,6 +1,82 @@
$Id: Changelog.txt,v 1.152 2011/07/25 18:02:11 nanard Exp $
$Id: Changelog.txt,v 1.177 2012/08/29 07:51:29 nanard Exp $
miniUPnP client Changelog.
2012/08/29:
Python 3 support (thanks to Christopher Foo)
2012/08/11:
Fix a memory link in UPNP_GetValidIGD()
Try to handle scope id in link local IPv6 URL under MS Windows
2012/07/20:
Disable HAS_IP_MREQN on DragonFly BSD
2012/06/28:
GetUPNPUrls() now inserts scope into link-local IPv6 addresses
2012/06/23:
More error return checks in upnpc.c
#define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
parseURL() now parses IPv6 addresses scope
new parameter for miniwget() : IPv6 address scope
increment API_VERSION to 9
2012/06/20:
fixed CMakeLists.txt
2012/05/29
Improvements in testminiwget.sh
VERSION 1.7 : released 2012/05/24
2012/05/01:
Cleanup settings of CFLAGS in Makefile
Fix signed/unsigned integer comparaisons
2012/04/20:
Allow to specify protocol with TCP or UDP for -A option
2012/04/09:
Only try to fetch XML description once in UPNP_GetValidIGD()
Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments.
2012/04/05:
minor improvements to minihttptestserver.c
2012/03/15:
upnperrors.c returns valid error string for unrecognized error codes
2012/03/08:
make minihttptestserver listen on loopback interface instead of 0.0.0.0
2012/01/25:
Maven installation thanks to Alexey Kuznetsov
2012/01/21:
Replace WIN32 macro by _WIN32
2012/01/19:
Fixes in java wrappers thanks to Alexey Kuznetsov :
https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc
Make and install .deb packages (python) thanks to Alexey Kuznetsov :
https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc
2012/01/07:
The multicast interface can now be specified by name with IPv4.
2012/01/02:
Install man page
2011/11/25:
added header to Port Mappings list in upnpc.c
2011/10/09:
Makefile : make clean now removes jnaerator generated files.
MINIUPNPC_VERSION in miniupnpc.h (updated by make)
2011/09/12:
added rootdescURL to UPNPUrls structure.
VERSION 1.6 : released 2011/07/25
2011/07/25:
@ -236,7 +312,7 @@ VERSION 1.2 :
small modif to make Clang happy :)
2008/07/17:
#define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
#define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
2008/07/14:
include declspec.h in installation (to /usr/include/miniupnpc)
@ -258,7 +334,7 @@ VERSION 1.1 :
improved python module error/exception reporting.
2008/04/23:
Completely rewrite igd_desc_parse.c in order to be compatible with
Completely rewrite igd_desc_parse.c in order to be compatible with
Linksys WAG200G
Added testigddescparse
updated python module
@ -281,7 +357,7 @@ VERSION 1.0 :
improved make install :)
2007/12/22:
Adding upnperrors.c/h to provide a strupnperror() function
Adding upnperrors.c/h to provide a strupnperror() function
used to translate UPnP error codes to string.
2007/12/19:

View File

@ -1,5 +1,5 @@
MiniUPnPc
Copyright (c) 2005-2011, Thomas BERNARD
Copyright (c) 2005-2011, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,29 +1,48 @@
# $Id: Makefile,v 1.81 2011/06/21 15:24:14 nanard Exp $
# $Id: Makefile,v 1.98 2012/08/29 07:51:30 nanard Exp $
# MiniUPnP Project
# http://miniupnp.free.fr/
# (c) 2005-2011 Thomas Bernard
# http://miniupnp.tuxfamily.org/
# https://github.com/miniupnp/miniupnp
# (c) 2005-2012 Thomas Bernard
# to install use :
# $ PREFIX=/tmp/dummylocation make install
# or
# $ INSTALLPREFIX=/usr/local make install
# or
# or
# make install (will go to /usr/bin, /usr/lib, etc...)
OS = $(shell uname -s)
VERSION = $(shell cat VERSION)
ifeq ($(OS), Darwin)
JARSUFFIX=mac
endif
ifeq ($(OS), Linux)
JARSUFFIX=linux
endif
CC ?= gcc
#AR = gar
#CFLAGS = -O -Wall -g -DDEBUG
CFLAGS ?= -O -Wall -DNDEBUG -DMINIUPNPC_SET_SOCKET_TIMEOUT -Wstrict-prototypes
#CFLAGS = -O -g -DDEBUG
CFLAGS ?= -O
CFLAGS += -Wall
CFLAGS += -W -Wstrict-prototypes
CFLAGS += -fno-common
CFLAGS += -DMINIUPNPC_SET_SOCKET_TIMEOUT
CFLAGS += -DMINIUPNPC_GET_SRC_ADDR
CFLAGS += -D_BSD_SOURCE -D_POSIX_C_SOURCE=1
CFLAGS += -ansi
# -DNO_GETADDRINFO
INSTALL = install
SH = /bin/sh
JAVA = java
# see http://code.google.com/p/jnaerator/
JNAERATOR = jnaerator-0.9.3.jar
JNAERATOR = jnaerator-0.9.7.jar
JNAERATORBASEURL = http://jnaerator.googlecode.com/files/
#following libs are needed on Solaris
#LDLIBS=-lsocket -lnsl -lresolv
# APIVERSION is used to build SONAME
APIVERSION = 8
APIVERSION = 9
SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \
upnpc.c upnpcommands.c upnpreplyparse.c testminixml.c \
@ -54,7 +73,7 @@ ifeq ($(OS), Darwin)
SHAREDLIBRARY = libminiupnpc.dylib
SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib
CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS)
else
else
SHAREDLIBRARY = libminiupnpc.so
SONAME = $(SHAREDLIBRARY).$(APIVERSION)
endif
@ -85,6 +104,7 @@ INSTALLPREFIX ?= $(PREFIX)/usr
INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc
INSTALLDIRLIB = $(INSTALLPREFIX)/lib
INSTALLDIRBIN = $(INSTALLPREFIX)/bin
INSTALLDIRMAN = $(INSTALLPREFIX)/share/man
FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES)
ifneq ($(OS), AmigaOS)
@ -92,12 +112,14 @@ FILESTOINSTALL := $(FILESTOINSTALL) $(SHAREDLIBRARY)
endif
.PHONY: install clean depend all check everything \
installpythonmodule
.PHONY: install clean depend all check test everything \
installpythonmodule updateversion
# validateminixml validateminiwget
all: $(LIBRARY) $(EXECUTABLES)
test: check
check: validateminixml validateminiwget
everything: all $(EXECUTABLES_ADDTESTS)
@ -109,6 +131,13 @@ pythonmodule: $(LIBRARY) miniupnpcmodule.c setup.py
installpythonmodule: pythonmodule
python setup.py install
pythonmodule3: $(LIBRARY) miniupnpcmodule.c setup.py
python3 setup.py build
touch $@
installpythonmodule3: pythonmodule3
python3 setup.py install
validateminixml: minixmlvalid
@echo "minixml validation test"
./minixmlvalid
@ -122,11 +151,17 @@ validateminiwget: testminiwget minihttptestserver testminiwget.sh
clean:
$(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h
# clean python stuff
$(RM) pythonmodule validateminixml
$(RM) pythonmodule pythonmodule3 validateminixml validateminiwget
$(RM) -r build/ dist/
#python setup.py clean
# clean jnaerator stuff
$(RM) _jnaerator.* java/miniupnpc_$(OS).jar
install: $(FILESTOINSTALL)
updateversion: miniupnpc.h
cp miniupnpc.h miniupnpc.h.bak
sed 's/\(.*MINIUPNPC_API_VERSION\s\+\)[0-9]\+/\1$(APIVERSION)/' < miniupnpc.h.bak > miniupnpc.h
install: updateversion $(FILESTOINSTALL)
$(INSTALL) -d $(INSTALLDIRINC)
$(INSTALL) -m 644 $(HEADERS) $(INSTALLDIRINC)
$(INSTALL) -d $(INSTALLDIRLIB)
@ -142,6 +177,11 @@ else
$(INSTALL) -m 755 upnpc-shared $(INSTALLDIRBIN)/upnpc
endif
$(INSTALL) -m 755 external-ip.sh $(INSTALLDIRBIN)/external-ip
ifneq ($(OS), AmigaOS)
$(INSTALL) -d $(INSTALLDIRMAN)/man3
$(INSTALL) man3/miniupnpc.3 $(INSTALLDIRMAN)/man3/miniupnpc.3
endif
cleaninstall:
$(RM) -r $(INSTALLDIRINC)
@ -156,7 +196,8 @@ $(LIBRARY): $(LIBOBJS)
$(SHAREDLIBRARY): $(LIBOBJS)
ifeq ($(OS), Darwin)
$(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(SONAME) -o $@ $^
# $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(SONAME) -o $@ $^
$(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(INSTALLDIRLIB)/$(SONAME) -o $@ $^
else
$(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^
endif
@ -177,11 +218,47 @@ testupnpreplyparse: $(TESTUPNPREPLYPARSE)
testigddescparse: $(TESTIGDDESCPARSE)
miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh
miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh VERSION
$(SH) updateminiupnpcstrings.sh
jar: $(SHAREDLIBRARY)
$(JAVA) -jar $(JNAERATOR) -library miniupnpc miniupnpc.h declspec.h upnpcommands.h upnpreplyparse.h igd_desc_parse.h miniwget.h upnperrors.h $(SHAREDLIBRARY) -package fr.free.miniupnp -o . -jar java/miniupnpc_$(OS).jar -v
jnaerator-0.9.8-shaded.jar:
wget $(JNAERATORBASEURL)/$@ || curl -o $@ $(JNAERATORBASEURL)/$@
jnaerator-0.9.7.jar:
wget $(JNAERATORBASEURL)/$@ || curl -o $@ $(JNAERATORBASEURL)/$@
jnaerator-0.9.3.jar:
wget $(JNAERATORBASEURL)/$@ || curl -o $@ $(JNAERATORBASEURL)/$@
jar: $(SHAREDLIBRARY) $(JNAERATOR)
$(JAVA) -jar $(JNAERATOR) -library miniupnpc \
miniupnpc.h declspec.h upnpcommands.h upnpreplyparse.h \
igd_desc_parse.h miniwget.h upnperrors.h $(SHAREDLIBRARY) \
-package fr.free.miniupnp -o . -jar java/miniupnpc_$(JARSUFFIX).jar -v
mvn_install:
mvn install:install-file -Dfile=java/miniupnpc_$(JARSUFFIX).jar \
-DgroupId=com.github \
-DartifactId=miniupnp \
-Dversion=$(VERSION) \
-Dpackaging=jar \
-Dclassifier=$(JARSUFFIX) \
-DgeneratePom=true \
-DcreateChecksum=true
# make .deb packages
deb: /usr/share/pyshared/stdeb all
(python setup.py --command-packages=stdeb.command bdist_deb)
# install .deb packages
ideb:
(sudo dpkg -i deb_dist/*.deb)
/usr/share/pyshared/stdeb: /usr/share/doc/python-all-dev
(sudo apt-get install python-stdeb)
/usr/share/doc/python-all-dev:
(sudo apt-get install python-all-dev)
minihttptestserver: minihttptestserver.o

View File

@ -1,18 +1,24 @@
Project: miniupnp
Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
github: https://github.com/miniupnp/miniupnp
freecode: http://freecode.com/projects/miniupnp
Author: Thomas Bernard
Copyright (c) 2005-2011 Thomas Bernard
Copyright (c) 2005-2012 Thomas Bernard
This software is subject to the conditions detailed in the
LICENSE file provided within this distribution.
For the comfort of Win32 users, bsdqueue.h is included in the distribution.
Its licence is included in the header of the file.
bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system.
* miniupnp Client *
* miniUPnP Client - miniUPnPc *
To compile, simply run 'gmake' (could be 'make' on your system).
Under win32, to compile with MinGW, type "mingw32make.bat".
MS Visual C solution and project files are supplied in the msvc/ subdirectory.
The compilation is known to work under linux, FreeBSD,
OpenBSD, MacOS X, AmigaOS and cygwin.
The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
@ -23,7 +29,7 @@ To install the library and headers on the system use :
> make install
> exit
alternatively, to install in a specific location, use :
alternatively, to install into a specific location, use :
> INSTALLPREFIX=/usr/local make install
upnpc.c is a sample client using the libminiupnpc.
@ -41,9 +47,10 @@ and -lminiupnpc for the link
Discovery process is speeded up when MiniSSDPd is running on the machine.
* Python module *
you can build a python module with 'make pythonmodule'
you can build a python module with 'make pythonmodule'
and install it with 'make installpythonmodule'.
setup.py (and setupmingw32.py) are included in the distribution.

View File

@ -1,7 +1,7 @@
/* $Id: connecthostport.c,v 1.5 2011/04/09 08:49:50 nanard Exp $ */
/* $Id: connecthostport.c,v 1.9 2012/06/26 00:00:27 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2010-2011 Thomas Bernard
* Copyright (c) 2010-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
@ -13,7 +13,7 @@
#include <string.h>
#include <stdio.h>
#ifdef WIN32
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
@ -21,12 +21,13 @@
#define snprintf _snprintf
#define herror
#define socklen_t int
#else /* #ifdef WIN32 */
#else /* #ifdef _WIN32 */
#include <unistd.h>
#include <sys/param.h>
#include <errno.h>
#define closesocket close
#include <netdb.h>
#include <netinet/in.h>
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */
#define MINIUPNPC_IGNORE_EINTR
@ -34,10 +35,10 @@
#include <sys/types.h>
#include <sys/socket.h>
#endif /* #ifndef USE_GETHOSTBYNAME */
#endif /* #else WIN32 */
#endif /* #else _WIN32 */
/* definition of PRINT_SOCKET_ERROR */
#ifdef WIN32
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
@ -52,7 +53,8 @@
/* connecthostport()
* return a socket connected (TCP) to the host and port
* or -1 in case of error */
int connecthostport(const char * host, unsigned short port)
int connecthostport(const char * host, unsigned short port,
unsigned int scope_id)
{
int s, n;
#ifdef USE_GETHOSTBYNAME
@ -67,7 +69,7 @@ int connecthostport(const char * host, unsigned short port)
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
struct timeval timeout;
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
#ifdef USE_GETHOSTBYNAME
hp = gethostbyname(host);
if(hp == NULL)
@ -145,10 +147,12 @@ int connecthostport(const char * host, unsigned short port)
if(host[0] == '[')
{
/* literal ip v6 address */
int i;
for(i = 0; host[i+1] && (host[i+1] != ']') && i < MAXHOSTNAMELEN; i++)
int i, j;
for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
{
tmp_host[i] = host[i+1];
tmp_host[i] = host[j];
if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */
j+=2; /* skip "25" */
}
tmp_host[i] = '\0';
}
@ -160,7 +164,7 @@ int connecthostport(const char * host, unsigned short port)
n = getaddrinfo(tmp_host, port_str, &hints, &ai);
if(n != 0)
{
#ifdef WIN32
#ifdef _WIN32
fprintf(stderr, "getaddrinfo() error : %d\n", n);
#else
fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
@ -173,6 +177,10 @@ int connecthostport(const char * host, unsigned short port)
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if(s < 0)
continue;
if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
addr6->sin6_scope_id = scope_id;
}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
/* setting a 3 seconds timeout for the connect() call */
timeout.tv_sec = 3;

View File

@ -1,7 +1,7 @@
/* $Id: minisoap.c,v 1.21 2011/03/22 19:15:35 nanard Exp $ */
/* $Id: minisoap.c,v 1.22 2012/01/21 13:30:31 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2009 Thomas Bernard
* Copyright (c) 2005-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
*
@ -9,7 +9,7 @@
*/
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#ifdef _WIN32
#include <io.h>
#include <winsock2.h>
#define snprintf _snprintf
@ -24,7 +24,7 @@
/* only for malloc */
#include <stdlib.h>
#ifdef WIN32
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
@ -57,7 +57,7 @@ httpWrite(int fd, const char * body, int bodysize,
/* disable send on the socket */
/* draytek routers dont seems to like that... */
#if 0
#ifdef WIN32
#ifdef _WIN32
if(shutdown(fd, SD_SEND)<0) {
#else
if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/

View File

@ -1,30 +1,23 @@
/* $Id: minissdpc.c,v 1.14 2010/11/25 09:57:25 nanard Exp $ */
/* $Id: minissdpc.c,v 1.16 2012/03/05 19:42:46 nanard Exp $ */
/* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD
* copyright (c) 2005-2009 Thomas Bernard
* copyright (c) 2005-2012 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
/*#include <syslog.h>*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <sys/types.h>
#if defined(WIN32) || defined(__amigaos__) || defined(__amigaos4__)
#ifdef WIN32
#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#include <winsock.h>
#ifndef WIN32
#include <stdint.h>
#else
//#include "types.h"
#define uint16_t unsigned short
typedef SSIZE_T ssize_t;
#endif
#endif
#if defined(__amigaos__) || defined(__amigaos4__)
#include <sys/socket.h>
@ -127,7 +120,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
p += stsize;
tmp->buffer[urlsize+1+stsize] = '\0';
devlist = tmp;
/* added for compatibility with recent versions of MiniSSDPd
/* added for compatibility with recent versions of MiniSSDPd
* >= 2007/12/19 */
DECODELENGTH(usnsize, p);
p += usnsize;

View File

@ -1,14 +1,10 @@
/* $Id: miniupnpc.c,v 1.95 2011/05/15 21:42:26 nanard Exp $ */
/* $Id: miniupnpc.c,v 1.110 2012/08/11 05:52:48 nanard Exp $ */
/* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD
* copyright (c) 2005-2011 Thomas Bernard
* copyright (c) 2005-2012 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENSE file. */
#if defined(__APPLE__)
#define MACOSX 1
#define _DARWIN_C_SOURCE 1
#endif
#define __EXTENSIONS__ 1
#if !defined(MACOSX) && !defined(__sun)
#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__)
@ -21,10 +17,14 @@
#endif
#endif
#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(MACOSX) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun)
#define HAS_IP_MREQN
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#ifdef _WIN32
/* Win32 Specific includes and defines */
#include <winsock2.h>
#include <ws2tcpip.h>
@ -39,7 +39,7 @@
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */
#define MAXHOSTNAMELEN 64
#else /* #ifdef WIN32 */
#else /* #ifdef _WIN32 */
/* Standard POSIX includes */
#include <unistd.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
@ -61,7 +61,7 @@
#include <strings.h>
#include <errno.h>
#define closesocket close
#endif /* #else WIN32 */
#endif /* #else _WIN32 */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
#include <sys/time.h>
#endif
@ -79,7 +79,7 @@
#include "connecthostport.h"
#include "receivedata.h"
#ifdef WIN32
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
@ -189,12 +189,11 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service,
strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
soapbody + sizeof(soapbody) - p);
}
if(!parseURL(url, hostname, &port, &path)) return NULL;
if(s<0)
{
s = connecthostport(hostname, port);
if(s < 0)
{
if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
if(s < 0) {
s = connecthostport(hostname, port, 0);
if(s < 0) {
/* failed to connect */
return NULL;
}
}
@ -230,8 +229,9 @@ char * simpleUPnPcommand(int s, const char * url, const char * service,
{
char * buf;
#if 1
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
/*
#else
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
if (!buf || *bufsize == 0)
{
@ -240,7 +240,7 @@ char * simpleUPnPcommand(int s, const char * url, const char * service,
#endif
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
}
*/
#endif
return buf;
}
@ -327,8 +327,9 @@ upnpDiscover(int delay, const char * multicastif,
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = 0;
unsigned int scope_id = 0;
int opt = 1;
static const char MSearchMsgFmt[] =
static const char MSearchMsgFmt[] =
"M-SEARCH * HTTP/1.1\r\n"
"HOST: %s:" XSTR(PORT) "\r\n"
"ST: %s\r\n"
@ -358,14 +359,14 @@ upnpDiscover(int delay, const char * multicastif,
int rv;
struct addrinfo hints, *servinfo, *p;
#endif
#ifdef WIN32
#ifdef _WIN32
MIB_IPFORWARDROW ip_forward;
#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 ! */
if(!minissdpdsock)
minissdpdsock = "/var/run/minissdpd.sock";
@ -383,7 +384,7 @@ upnpDiscover(int delay, const char * multicastif,
deviceIndex = 0;
#endif
/* fallback to direct discovery */
#ifdef WIN32
#ifdef _WIN32
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
#else
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
@ -410,8 +411,8 @@ upnpDiscover(int delay, const char * multicastif,
p->sin_port = htons(PORT);
p->sin_addr.s_addr = INADDR_ANY;
}
#ifdef WIN32
/* This code could help us to use the right Network interface for
#ifdef _WIN32
/* This code could help us to use the right Network interface for
* SSDP multicast traffic */
/* 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) */
@ -470,7 +471,7 @@ upnpDiscover(int delay, const char * multicastif,
}
#endif
#ifdef WIN32
#ifdef _WIN32
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
#else
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
@ -485,7 +486,7 @@ upnpDiscover(int delay, const char * multicastif,
if(multicastif)
{
if(ipv6) {
#if !defined(WIN32)
#if !defined(_WIN32)
/* 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 */
@ -502,10 +503,28 @@ upnpDiscover(int delay, const char * multicastif,
} 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;
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
if(mc_if.s_addr != INADDR_NONE)
{
PRINT_SOCKET_ERROR("setsockopt");
((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)
{
PRINT_SOCKET_ERROR("setsockopt");
}
} else {
#ifdef HAS_IP_MREQN
/* was not an ip address, try with an interface name */
struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */
memset(&reqn, 0, sizeof(struct ip_mreqn));
reqn.imr_ifindex = if_nametoindex(multicastif);
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt");
}
#else
#ifdef DEBUG
printf("Setting of multicast interface not supported with interface name.\n");
#endif
#endif
}
}
}
@ -568,7 +587,7 @@ upnpDiscover(int delay, const char * multicastif,
}
#else /* #ifdef NO_GETADDRINFO */
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_flags = */
if ((rv = getaddrinfo(ipv6
@ -577,7 +596,7 @@ upnpDiscover(int delay, const char * multicastif,
XSTR(PORT), &hints, &servinfo)) != 0) {
if(error)
*error = UPNPDISCOVER_SOCKET_ERROR;
#ifdef WIN32
#ifdef _WIN32
fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
#else
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
@ -586,13 +605,14 @@ upnpDiscover(int delay, const char * multicastif,
}
for(p = servinfo; p; p = p->ai_next) {
n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
#ifdef DEBUG
struct sockaddr_in *saddrin = (struct sockaddr_in *)p->ai_addr;
printf("sendto returned %d [%s] to host [%s]\n", n,bufr,inet_ntoa(saddrin->sin_addr));
#endif
if (n < 0) {
#ifdef DEBUG
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf);
}
#endif
PRINT_SOCKET_ERROR("sendto");
continue;
}
@ -606,12 +626,7 @@ upnpDiscover(int delay, const char * multicastif,
#endif /* #ifdef NO_GETADDRINFO */
}
/* Waiting for SSDP REPLY packet to M-SEARCH */
n = receivedata(sudp, bufr, sizeof(bufr), delay);
#ifdef DEBUG
printf("receivedata returned %d [%s]\n", n,bufr);
#endif
n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
if (n < 0) {
/* error */
if(error)
@ -671,6 +686,7 @@ upnpDiscover(int delay, const char * multicastif,
tmp->buffer[urlsize] = '\0';
memcpy(tmp->buffer + urlsize + 1, st, stsize);
tmp->buffer[urlsize+1+stsize] = '\0';
tmp->scope_id = scope_id;
devlist = tmp;
}
}
@ -717,14 +733,31 @@ url_cpy_or_cat(char * dst, const char * src, int n)
/* Prepare the Urls for usage...
*/
LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
const char * descURL)
LIBSPEC void
GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
const char * descURL, unsigned int scope_id)
{
char * p;
int n1, n2, n3, n4;
#ifdef IF_NAMESIZE
char ifname[IF_NAMESIZE];
#else
char scope_str[8];
#endif
n1 = strlen(data->urlbase);
if(n1==0)
n1 = strlen(descURL);
if(scope_id != 0) {
#ifdef IF_NAMESIZE
if(if_indextoname(scope_id, ifname)) {
n1 += 3 + strlen(ifname); /* 3 == strlen(%25) */
}
#else
/* under windows, scope is numerical */
snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
#endif
}
n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
n2 = n1; n3 = n1; n4 = n1;
n1 += strlen(data->first.scpdurl);
@ -732,21 +765,44 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
n3 += strlen(data->CIF.controlurl);
n4 += strlen(data->IPv6FC.controlurl);
/* allocate memory to store URLs */
urls->ipcondescURL = (char *)malloc(n1);
urls->controlURL = (char *)malloc(n2);
urls->controlURL_CIF = (char *)malloc(n3);
urls->controlURL_6FC = (char *)malloc(n4);
/* maintenant on chope la desc du WANIPConnection */
/* strdup descURL */
urls->rootdescURL = strdup(descURL);
/* get description of WANIPConnection */
if(data->urlbase[0] != '\0')
strncpy(urls->ipcondescURL, data->urlbase, n1);
else
strncpy(urls->ipcondescURL, descURL, n1);
p = strchr(urls->ipcondescURL+7, '/');
if(p) p[0] = '\0';
if(scope_id != 0) {
if(0 == memcmp(urls->ipcondescURL, "http://[fe80:", 13)) {
/* this is a linklocal IPv6 address */
p = strchr(urls->ipcondescURL, ']');
if(p) {
/* insert %25<scope> into URL */
#ifdef IF_NAMESIZE
memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, ifname, strlen(ifname));
#else
memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, scope_str, strlen(scope_str));
#endif
}
}
}
strncpy(urls->controlURL, urls->ipcondescURL, n2);
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->controlURL, data->first.controlurl, n2);
@ -780,6 +836,8 @@ FreeUPNPUrls(struct UPNPUrls * urls)
urls->controlURL_CIF = 0;
free(urls->controlURL_6FC);
urls->controlURL_6FC = 0;
free(urls->rootdescURL);
urls->rootdescURL = 0;
}
int
@ -801,6 +859,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
/* UPNP_GetValidIGD() :
* return values :
* -1 = Internal error
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
* 2 = A valid IGD has been found but it reported as
@ -817,11 +876,14 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen)
{
char * descXML;
int descXMLsize = 0;
struct xml_desc {
char * xml;
int size;
} * desc = NULL;
struct UPNPDev * dev;
int ndev = 0;
int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
int i;
int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
if(!devlist)
{
#ifdef DEBUG
@ -829,27 +891,42 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
#endif
return 0;
}
for(dev = devlist; dev; dev = dev->pNext)
ndev++;
if(ndev > 0)
{
desc = calloc(ndev, sizeof(struct xml_desc));
if(!desc)
return -1; /* memory allocation error */
}
for(state = 1; state <= 3; state++)
{
for(dev = devlist; dev; dev = dev->pNext)
for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
{
/* we should choose an internet gateway device.
* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
descXML = miniwget_getaddr(dev->descURL, &descXMLsize,
lanaddr, lanaddrlen);
if(descXML)
if(state == 1)
{
desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
lanaddr, lanaddrlen,
dev->scope_id);
#ifdef DEBUG
if(!desc[i].xml)
{
printf("error getting XML description %s\n", dev->descURL);
}
#endif
}
if(desc[i].xml)
{
ndev++;
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data);
free(descXML);
descXML = NULL;
parserootdesc(desc[i].xml, desc[i].size, data);
if(0==strcmp(data->CIF.servicetype,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
|| state >= 3 )
{
GetUPNPUrls(urls, data, dev->descURL);
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
@ -857,7 +934,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
UPNPIGD_IsConnected(urls, data));
#endif
if((state >= 2) || UPNPIGD_IsConnected(urls, data))
return state;
goto free_and_return;
FreeUPNPUrls(urls);
if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
@ -868,28 +945,32 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
GetUPNPUrls(urls, data, dev->descURL);
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL,
UPNPIGD_IsConnected(urls, data));
#endif
if((state >= 2) || UPNPIGD_IsConnected(urls, data))
return state;
goto free_and_return;
FreeUPNPUrls(urls);
}
}
memset(data, 0, sizeof(struct IGDdatas));
}
#ifdef DEBUG
else
{
printf("error getting XML description %s\n", dev->descURL);
}
#endif
}
}
return 0;
state = 0;
free_and_return:
if(desc) {
for(i = 0; i < ndev; i++) {
if(desc[i].xml) {
free(desc[i].xml);
}
}
free(desc);
}
return state;
}
/* UPNP_GetIGDFromUrl()
@ -906,14 +987,14 @@ UPNP_GetIGDFromUrl(const char * rootdescurl,
char * descXML;
int descXMLsize = 0;
descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
lanaddr, lanaddrlen);
lanaddr, lanaddrlen, 0);
if(descXML) {
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data);
free(descXML);
descXML = NULL;
GetUPNPUrls(urls, data, rootdescurl);
GetUPNPUrls(urls, data, rootdescurl, 0);
return 1;
} else {
return 0;

View File

@ -1,15 +1,16 @@
/* $Id: miniwget.c,v 1.52 2011/06/17 22:59:42 nanard Exp $ */
/* $Id: miniwget.c,v 1.58 2012/08/11 05:52:49 nanard Exp $ */
/* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
* Copyright (c) 2005-2012 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
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
@ -24,7 +25,7 @@
#define strncasecmp memicmp
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */
#else /* #ifdef WIN32 */
#else /* #ifdef _WIN32 */
#include <unistd.h>
#include <sys/param.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
@ -33,13 +34,15 @@
#include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#define closesocket close
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */
#define MINIUPNPC_IGNORE_EINTR
#endif /* #else WIN32 */
#endif /* #else _WIN32 */
#if defined(__sun) || defined(sun)
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif
@ -67,22 +70,20 @@ getHTTPResponse(int s, int * size)
unsigned int bytestocopy = 0;
/* buffers : */
char * header_buf;
int header_buf_len = 2048;
int header_buf_used = 0;
unsigned int header_buf_len = 2048;
unsigned int header_buf_used = 0;
char * content_buf;
char *content_buf_new;
int content_buf_len = 2048;
int content_buf_used = 0;
unsigned int content_buf_len = 2048;
unsigned int content_buf_used = 0;
char chunksize_buf[32];
int chunksize_buf_index;
unsigned int chunksize_buf_index;
header_buf = malloc(header_buf_len);
header_buf[0] = '\0';
content_buf = malloc(content_buf_len);
chunksize_buf[0] = '\0';
chunksize_buf_index = 0;
while((n = receivedata(s, buf, 2048, 5000)) > 0)
while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0)
{
if(endofheaders == 0)
{
@ -91,25 +92,22 @@ getHTTPResponse(int s, int * size)
int colon=0;
int valuestart=0;
if(header_buf_used + n > header_buf_len) {
char *header_buf_new = realloc(header_buf, header_buf_used + n);
if(header_buf_new != NULL) {
header_buf = header_buf_new;
header_buf_len = header_buf_used + n;
}
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)) {
while(i < ((int)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') {
if(i < (int)header_buf_used && header_buf[i] == '\r') {
i++;
if(i < header_buf_used && header_buf[i] == '\n') {
if(i < (int)header_buf_used && header_buf[i] == '\n') {
endofheaders = i+1;
}
}
@ -165,7 +163,7 @@ getHTTPResponse(int s, int * size)
linestart = i;
colon = linestart;
valuestart = 0;
}
}
}
/* copy the remaining of the received data back to buf */
n = header_buf_used - endofheaders;
@ -199,7 +197,7 @@ getHTTPResponse(int s, int * size)
i++; /* discarding chunk-extension */
if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') {
int j;
unsigned int j;
for(j = 0; j < chunksize_buf_index; j++) {
if(chunksize_buf[j] >= '0'
&& chunksize_buf[j] <= '9')
@ -226,20 +224,16 @@ getHTTPResponse(int s, int * size)
goto end_of_stream;
}
}
bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i);
if((int)(content_buf_used + bytestocopy) > content_buf_len)
bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
if((content_buf_used + bytestocopy) > content_buf_len)
{
if(content_length >= content_buf_used + (int)bytestocopy) {
if(content_length >= (int)(content_buf_used + bytestocopy)) {
content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + bytestocopy;
}
else {
content_buf_len = content_buf_used + (int)bytestocopy;
}
content_buf_new = (char *)realloc((void *)content_buf,
content_buf = (char *)realloc((void *)content_buf,
content_buf_len);
if(content_buf_new) {
content_buf = content_buf_new;
}
}
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
content_buf_used += bytestocopy;
@ -251,29 +245,26 @@ getHTTPResponse(int s, int * size)
{
/* not chunked */
if(content_length > 0
&& (content_buf_used + n) > content_length) {
&& (int)(content_buf_used + n) > content_length) {
/* skipping additional bytes */
n = content_length - content_buf_used;
}
if(content_buf_used + n > content_buf_len)
{
if(content_length >= content_buf_used + n) {
if(content_length >= (int)(content_buf_used + n)) {
content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + n;
}
content_buf_new = (char *)realloc((void *)content_buf,
content_buf = (char *)realloc((void *)content_buf,
content_buf_len);
if(content_buf_new) {
content_buf = content_buf_new;
}
}
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)
if(content_length > 0 && (int)content_buf_used >= content_length)
{
#ifdef DEBUG
printf("End of HTTP content\n");
@ -296,10 +287,10 @@ end_of_stream:
* do all the work.
* Return NULL if something failed. */
static void *
miniwget3(const char * url, const char * host,
miniwget3(const char * host,
unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len,
const char * httpversion)
const char * httpversion, unsigned int scope_id)
{
char buf[2048];
int s;
@ -309,7 +300,7 @@ miniwget3(const char * url, const char * host,
void * content;
*size = 0;
s = connecthostport(host, port);
s = connecthostport(host, port, scope_id);
if(s < 0)
return NULL;
@ -355,7 +346,7 @@ miniwget3(const char * url, const char * host,
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV);
if(n != 0) {
#ifdef WIN32
#ifdef _WIN32
fprintf(stderr, "getnameinfo() failed : %d\n", n);
#else
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
@ -400,24 +391,29 @@ miniwget3(const char * url, const char * host,
/* miniwget2() :
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
static void *
miniwget2(const char * url, const char * host,
miniwget2(const char * host,
unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len)
int * size, char * addr_str, int addr_str_len,
unsigned int scope_id)
{
char * respbuffer;
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
/*
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
#if 1
respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1", scope_id);
#else
respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.0", scope_id);
if (*size == 0)
{
#ifdef DEBUG
printf("Retrying with HTTP/1.1\n");
#endif
free(respbuffer);
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1", scope_id);
}
*/
#endif
return respbuffer;
}
@ -429,12 +425,15 @@ miniwget2(const char * url, const char * host,
* url : source string not modified
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
* port : port (destination)
* path : pointer to the path part of the URL
* path : pointer to the path part of the URL
*
* Return values :
* 0 - Failure
* 1 - Success */
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
int
parseURL(const char * url,
char * hostname, unsigned short * port,
char * * path, unsigned int * scope_id)
{
char * p1, *p2, *p3;
if(!url)
@ -450,7 +449,43 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
if(*p1 == '[')
{
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
char * scope;
scope = strchr(p1, '%');
p2 = strchr(p1, ']');
if(p2 && scope && scope < p2 && scope_id) {
/* parse scope */
#ifdef IF_NAMESIZE
char tmp[IF_NAMESIZE];
int l;
scope++;
/* "%25" is just '%' in URL encoding */
if(scope[0] == '2' && scope[1] == '5')
scope += 2; /* skip "25" */
l = p2 - scope;
if(l >= IF_NAMESIZE)
l = IF_NAMESIZE - 1;
memcpy(tmp, scope, l);
tmp[l] = '\0';
*scope_id = if_nametoindex(tmp);
if(*scope_id == 0) {
*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
}
#else
/* under windows, scope is numerical */
char tmp[8];
int l;
scope++;
/* "%25" is just '%' in URL encoding */
if(scope[0] == '2' && scope[1] == '5')
scope += 2; /* skip "25" */
l = p2 - scope;
if(l >= sizeof(tmp))
l = sizeof(tmp) - 1;
memcpy(tmp, scope, l);
tmp[l] = '\0';
*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
#endif
}
p3 = strchr(p1, '/');
if(p2 && p3)
{
@ -500,35 +535,40 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
return 1;
}
void * miniwget(const char * url, int * size)
void *
miniwget(const char * url, int * size, unsigned int scope_id)
{
unsigned short port;
char * path;
/* protocol://host:port/chemin */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(!parseURL(url, hostname, &port, &path))
if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL;
#ifdef DEBUG
printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id);
#endif
return miniwget2(url, hostname, port, path, size, 0, 0);
return miniwget2(hostname, port, path, size, 0, 0, scope_id);
}
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
void *
miniwget_getaddr(const char * url, int * size,
char * addr, int addrlen, unsigned int scope_id)
{
unsigned short port;
char * path;
/* protocol://host:port/chemin */
/* protocol://host:port/path */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(addr)
addr[0] = '\0';
if(!parseURL(url, hostname, &port, &path))
if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL;
#ifdef DEBUG
printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id);
#endif
return miniwget2(url, hostname, port, path, size, addr, addrlen);
return miniwget2(hostname, port, path, size, addr, addrlen, scope_id);
}

View File

@ -1,10 +1,10 @@
/* $Id: minixml.c,v 1.9 2011/02/07 13:44:57 nanard Exp $ */
/* $Id: minixml.c,v 1.10 2012/03/05 19:42:47 nanard Exp $ */
/* minixml.c : the minimum size a xml parser can be ! */
/* Project : miniupnp
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author : Thomas Bernard
Copyright (c) 2005-2011, Thomas BERNARD
Copyright (c) 2005-2011, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -149,7 +149,7 @@ static void parseelt(struct xmlparser * p)
return;
}
if(memcmp(p->xml, "<![CDATA[", 9) == 0)
{
{
/* CDATA handling */
p->xml += 9;
data = p->xml;

View File

@ -1,4 +1,4 @@
/* $Id: minixmlvalid.c,v 1.4 2011/02/07 13:44:57 nanard Exp $ */
/* $Id: minixmlvalid.c,v 1.6 2012/05/01 16:24:07 nanard Exp $ */
/* MiniUPnP Project
* http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
* minixmlvalid.c :
@ -32,7 +32,7 @@ int evtlistcmp(struct eventlist * a, struct eventlist * b)
if(a->n != b->n)
{
printf("event number not matching : %d != %d\n", a->n, b->n);
//return 1;
/*return 1;*/
}
for(i=0; i<a->n; i++)
{
@ -82,7 +82,7 @@ static const struct event evtref[] =
{ELTEND, "elt2b", 5},
{ELTEND, "elt2a", 5},
{ELTEND, "xmlroot", 7}
};
};
void startelt(void * data, const char * p, int l)
{
@ -148,6 +148,8 @@ int testxmlparser(const char * xml, int size)
int main(int argc, char * * argv)
{
int r;
(void)argc; (void)argv;
r = testxmlparser(xmldata, sizeof(xmldata)-1);
if(r)
printf("minixml validation test failed\n");

View File

@ -1,7 +1,7 @@
/* $Id: portlistingparse.c,v 1.4 2011/03/18 11:02:17 nanard Exp $ */
/* $Id: portlistingparse.c,v 1.6 2012/05/29 10:26:51 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2011 Thomas Bernard
* (c) 2011 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <string.h>
@ -71,6 +71,8 @@ static void
endelt(void * d, const char * name, int l)
{
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
(void)name;
(void)l;
pdata->curelt = PortMappingEltNone;
}

View File

@ -1,12 +1,13 @@
/* $Id: receivedata.c,v 1.1 2011/04/11 08:21:47 nanard Exp $ */
/* $Id: receivedata.c,v 1.4 2012/06/23 22:34:47 nanard Exp $ */
/* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2011 Thomas Bernard
* Copyright (c) 2011-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
#include <stdio.h>
#ifdef WIN32
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
@ -17,6 +18,7 @@
#include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
#include <netinet/in.h>
#if !defined(__amigaos__) && !defined(__amigaos4__)
#include <poll.h>
#endif
@ -24,7 +26,7 @@
#define MINIUPNPC_IGNORE_EINTR
#endif
#ifdef WIN32
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
@ -33,10 +35,16 @@
#include "receivedata.h"
int
receivedata(int socket, char * data, int length, int timeout)
receivedata(int socket,
char * data, int length,
int timeout, unsigned int * scope_id)
{
#if MINIUPNPC_GET_SRC_ADDR
struct sockaddr_storage src_addr;
socklen_t src_addr_len = sizeof(src_addr);
#endif
int n;
#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
/* using poll */
struct pollfd fds[1]; /* for the poll */
#ifdef MINIUPNPC_IGNORE_EINTR
@ -55,8 +63,8 @@ receivedata(int socket, char * data, int length, int timeout)
/* timeout */
return 0;
}
#else /* !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
/* using select under WIN32 and amigaos */
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
/* using select under _WIN32 and amigaos */
fd_set socketSet;
TIMEVAL timeval;
FD_ZERO(&socketSet);
@ -69,12 +77,27 @@ receivedata(int socket, char * data, int length, int timeout)
return -1;
} else if(n == 0) {
return 0;
}
}
#endif
#if MINIUPNPC_GET_SRC_ADDR
n = recvfrom(socket, data, length, 0,
(struct sockaddr *)&src_addr, &src_addr_len);
#else
n = recv(socket, data, length, 0);
#endif
if(n<0) {
PRINT_SOCKET_ERROR("recv");
}
#if MINIUPNPC_GET_SRC_ADDR
if (src_addr.ss_family == AF_INET6) {
const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
#ifdef DEBUG
printf("scope_id=%u\n", src_addr6->sin6_scope_id);
#endif
if(scope_id)
*scope_id = src_addr6->sin6_scope_id;
}
#endif
return n;
}

View File

@ -1,13 +1,16 @@
#! /usr/bin/python
# $Id: setup.py,v 1.6 2011/01/04 09:46:08 nanard Exp $
# the MiniUPnP Project (c) 2007-2011 Thomas Bernard
# $Id: setup.py,v 1.9 2012/05/23 08:50:10 nanard Exp $
# the MiniUPnP Project (c) 2007-2012 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.5",
from distutils import sysconfig
sysconfig.get_config_vars()["OPT"] = ''
sysconfig.get_config_vars()["CFLAGS"] = ''
setup(name="miniupnpc", version="1.7",
ext_modules=[
Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
extra_objects=["libminiupnpc.a"])

View File

@ -1,12 +1,15 @@
#! /usr/bin/python
# $Id: setupmingw32.py,v 1.5 2011/05/15 21:18:43 nanard Exp $
# the MiniUPnP Project (c) 2007-2011 Thomas Bernard
# $Id: setupmingw32.py,v 1.8 2012/05/23 08:50:10 nanard Exp $
# the MiniUPnP Project (c) 2007-2012 Thomas Bernard
# http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
#
# python script to build the miniupnpc module under windows (using mingw32)
#
from distutils.core import setup, Extension
setup(name="miniupnpc", version="1.5",
from distutils import sysconfig
sysconfig.get_config_vars()["OPT"] = ''
sysconfig.get_config_vars()["CFLAGS"] = ''
setup(name="miniupnpc", version="1.7",
ext_modules=[
Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
libraries=["ws2_32", "iphlpapi"],

View File

@ -1,7 +1,7 @@
#!/bin/sh
# $Id: testminiwget.sh,v 1.4 2011/05/09 08:53:15 nanard Exp $
# $Id: testminiwget.sh,v 1.6 2012/05/29 13:03:40 nanard Exp $
# project miniupnp : http://miniupnp.free.fr/
# (c) 2011 Thomas Bernard
# (c) 2011-2012 Thomas Bernard
#
# test program for miniwget.c
# is usually invoked by "make check"
@ -12,10 +12,13 @@
# 3 - compares served and received data
# 4 - kills the local HTTP server and exits
#
# The script was tested and works with ksh, bash
# It fails to run with dash 0.5.5.1 because of "kill %1"
HTTPSERVEROUT=/tmp/httpserverout
EXPECTEDFILE=/tmp/expectedfile
DOWNLOADEDFILE=/tmp/downloadedfile
TMPDIR=`mktemp -d`
HTTPSERVEROUT="${TMPDIR}/httpserverout"
EXPECTEDFILE="${TMPDIR}/expectedfile"
DOWNLOADEDFILE="${TMPDIR}/downloadedfile"
#ADDR=localhost
ADDR="[::1]"
PORT=
@ -26,7 +29,8 @@ RET=0
# launching the test HTTP server
./minihttptestserver -6 -e $EXPECTEDFILE > $HTTPSERVEROUT &
while [ "$PORT" == "" ]; do
while [ -z "$PORT" ]; do
sleep 1
PORT=`cat $HTTPSERVEROUT | sed 's/Listening on port \([0-9]*\)/\1/' `
done
echo "Test HTTP server is listening on $PORT"
@ -72,8 +76,10 @@ if [ $RET -eq 0 ]; then
rm -f "${DOWNLOADEDFILE}.2"
rm -f "${DOWNLOADEDFILE}.3"
rm -f $EXPECTEDFILE $HTTPSERVEROUT
rmdir ${TMPDIR}
else
echo "at least one of the test FAILED"
echo "directory ${TMPDIR} is left intact"
fi
exit $RET

View File

@ -1,7 +1,7 @@
/* $Id: upnpc.c,v 1.88 2011/06/17 23:31:01 nanard Exp $ */
/* $Id: upnpc.c,v 1.97 2012/06/23 23:16:00 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
* Copyright (c) 2005-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
@ -9,16 +9,19 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
#ifdef _WIN32
#include <winsock2.h>
#define snprintf _snprintf
#else
/* for IPPROTO_TCP / IPPROTO_UDP */
#include <netinet/in.h>
#endif
#include "miniwget.h"
#include "miniupnpc.h"
#include "upnpcommands.h"
#include "upnperrors.h"
/* protofix() checks if protocol is "UDP" or "TCP"
/* protofix() checks if protocol is "UDP" or "TCP"
* returns NULL if not */
const char * protofix(const char * proto)
{
@ -26,7 +29,7 @@ const char * protofix(const char * proto)
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])
b = b && ( (proto[i] == proto_tcp[i])
|| (proto[i] == (proto_tcp[i] | 32)) );
if(b)
return proto_tcp;
@ -49,44 +52,47 @@ static void DisplayInfos(struct UPNPUrls * urls,
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
if(UPNP_GetConnectionTypeInfo(urls->controlURL,
data->first.servicetype,
connectionType) != UPNPCOMMAND_SUCCESS)
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);
else
printf("Connection Type : %s\n", connectionType);
if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS)
printf("GetStatusInfo failed.\n");
else
printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
status, uptime, lastconnerr);
timenow = time(NULL);
timestarted = timenow - uptime;
printf(" Time started : %s", ctime(&timestarted));
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);
if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
&brDown, &brUp) != UPNPCOMMAND_SUCCESS) {
printf("GetLinkLayerMaxBitRates failed.\n");
} else {
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");
}
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])
if(r != UPNPCOMMAND_SUCCESS) {
printf("GetExternalIPAddress failed. (errorcode=%d)\n", r);
} else {
printf("ExternalIPAddress = %s\n", externalIPAddress);
else
printf("GetExternalIPAddress failed.\n");
}
}
static void GetConnectionStatus(struct UPNPUrls * urls,
@ -119,6 +125,7 @@ static void ListRedirections(struct UPNPUrls * urls,
/*unsigned int num=0;
UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
printf("PortMappingNumberOfEntries : %u\n", num);*/
printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
do {
snprintf(index, 6, "%d", i);
rHost[0] = '\0'; enabled[0] = '\0';
@ -166,6 +173,7 @@ static void NewListRedirections(struct UPNPUrls * urls,
&pdata);
if(r == UPNPCOMMAND_SUCCESS)
{
printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
{
printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
@ -209,7 +217,7 @@ static void NewListRedirections(struct UPNPUrls * urls,
}
}
/* Test function
/* Test function
* 1 - get connection type
* 2 - get extenal ip address
* 3 - Add port mapping
@ -239,7 +247,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
fprintf(stderr, "invalid protocol\n");
return;
}
UPNP_GetExternalIPAddress(urls->controlURL,
data->first.servicetype,
externalIPAddress);
@ -247,7 +255,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
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)
@ -262,7 +270,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
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",
@ -301,7 +309,7 @@ static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
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);
@ -310,7 +318,7 @@ static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
}
/* Test function
/* Test function
* 1 - Add pinhole
* 2 - Check if pinhole is working from the IGD side */
static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data,
@ -319,27 +327,43 @@ static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data,
const char * proto, const char * lease_time)
{
char uniqueID[8];
//int isWorking = 0;
/*int isWorking = 0;*/
int r;
char proto_tmp[8];
if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time)
{
fprintf(stderr, "Wrong arguments\n");
return;
}
/*proto = protofix(proto);
if(!proto)
if(atoi(proto) == 0)
{
fprintf(stderr, "invalid protocol\n");
return;
}*/
const char * protocol;
protocol = protofix(proto);
if(protocol && (strcmp("TCP", protocol) == 0))
{
snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP);
proto = proto_tmp;
}
else if(protocol && (strcmp("UDP", protocol) == 0))
{
snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP);
proto = proto_tmp;
}
else
{
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));
remoteaddr, eport, intaddr, iport, r, strupnperror(r));
else
{
printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", intaddr, iport, remoteaddr, eport, uniqueID);
printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n",
remoteaddr, eport, intaddr, iport, 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));
@ -374,7 +398,7 @@ static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data,
}
}
/* Test function
/* Test function
* Get pinhole timeout
*/
static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data,
@ -464,7 +488,7 @@ int main(int argc, char ** argv)
int error = 0;
int ipv6 = 0;
#ifdef WIN32
#ifdef _WIN32
WSADATA wsaData;
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(nResult != NO_ERROR)
@ -473,7 +497,7 @@ int main(int argc, char ** argv)
return -1;
}
#endif
printf("upnpc : miniupnpc library test client. (c) 2006-2011 Thomas Bernard\n");
printf("upnpc : miniupnpc library test client. (c) 2006-2012 Thomas Bernard\n");
printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
"for more information.\n");
/* command line processing */
@ -529,7 +553,7 @@ int main(int argc, char ** argv)
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, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n");
fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n");
return 1;
}
@ -573,7 +597,6 @@ int main(int argc, char ** argv)
default:
printf("Found device (igd ?) : %s\n", urls.controlURL);
printf("Trying to continue anyway\n");
break;
}
printf("Local LAN ip address : %s\n", lanaddr);
#if 0
@ -663,7 +686,6 @@ int main(int argc, char ** argv)
default:
fprintf(stderr, "Unknown switch -%c\n", command);
retcode = 1;
break;
}
FreeUPNPUrls(&urls);

View File

@ -1,7 +1,7 @@
/* $Id: upnpcommands.c,v 1.37 2011/06/04 15:56:23 nanard Exp $ */
/* $Id: upnpcommands.c,v 1.40 2012/06/23 22:36:35 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
* Copyright (c) 2005-2012 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
@ -119,7 +119,7 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
LIBSPEC int
UPNP_GetStatusInfo(const char * controlURL,
const char * servicetype,
char * status,
char * status,
unsigned int * uptime,
char * lastconnerror)
{
@ -221,8 +221,8 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
* One of the values can be null
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
* One of the values can be null
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
LIBSPEC int
UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
@ -285,7 +285,7 @@ UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available
*
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
@ -741,16 +741,16 @@ UPNP_GetListOfPortMappings(const char * controlURL,
}
ClearNameValueList(&pdata);
//printf("%.*s", bufsize, buffer);
/*printf("%.*s", bufsize, buffer);*/
return ret;
}
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
LIBSPEC int
UPNP_GetFirewallStatus(const char * controlURL,
const char * servicetype,
int * firewallEnabled,
int * firewallEnabled,
int * inboundPinholeAllowed)
{
struct NameValueParserData pdata;
@ -868,7 +868,7 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype,
return UPNPCOMMAND_INVALID_ARGS;
AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
// RemoteHost can be wilcarded
/* RemoteHost can be wilcarded */
if(strncmp(remoteHost, "empty", 5)==0)
{
AddPinholeArgs[0].elt = "RemoteHost";
@ -912,7 +912,7 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype,
resVal = GetValueFromNameValueList(&pdata, "errorCode");
if(resVal)
{
//printf("AddPortMapping errorCode = '%s'\n", resVal);
/*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(resVal, "%d", &ret);
}

View File

@ -1,4 +1,4 @@
/* $Id: upnperrors.c,v 1.5 2011/04/10 11:19:36 nanard Exp $ */
/* $Id: upnperrors.c,v 1.6 2012/03/15 01:02:03 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2007 Thomas Bernard
@ -97,7 +97,7 @@ const char * strupnperror(int err)
s = "ExternalPortOnlySupportsWildcard";
break;
default:
s = NULL;
s = "UnknownError";
break;
}
return s;

View File

@ -1,7 +1,7 @@
/* $Id: upnpreplyparse.c,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
/* $Id: upnpreplyparse.c,v 1.12 2012/03/05 19:42:48 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2011 Thomas Bernard
* (c) 2006-2011 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -90,7 +90,7 @@ ClearNameValueList(struct NameValueParserData * pdata)
}
}
char *
char *
GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name)
{
@ -131,7 +131,7 @@ GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
}
#endif
/* debug all-in-one function
/* debug all-in-one function
* do parsing then display to stdout */
#ifdef DEBUG
void