- 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) if(NOT MINIUPNP_FOUND)
MESSAGE(STATUS "*** Using EMBEDDED miniupnpc since dev system does not have it... MINIUPNP_FOUND [${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) SET(DIRS_WITH_SRC ${DIRS_WITH_SRC} platform/miniupnpc)
else() else()
MESSAGE(STATUS "*** Using SHARED miniupnpc found in [${MINIUPNP_INCLUDE_DIR}] MINIUPNP_FOUND [${MINIUPNP_FOUND}] MINIUPNP_LIBRARY [${MINIUPNP_LIBRARY}]") 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_ #define _SYS_QUEUE_H_
/* /*
* This file defines five types of data structures: singly-linked lists, * This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues. * lists, simple queues, tail queues, and circular queues.
* *
* *
@ -95,7 +95,7 @@
struct name { \ struct name { \
struct type *slh_first; /* first element */ \ struct type *slh_first; /* first element */ \
} }
#define SLIST_HEAD_INITIALIZER(head) \ #define SLIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
@ -107,7 +107,7 @@ struct name { \
struct { \ struct { \
struct type *sle_next; /* next element */ \ struct type *sle_next; /* next element */ \
} }
/* /*
* Singly-linked List access methods. * Singly-linked List access methods.
*/ */
@ -322,8 +322,8 @@ struct { \
struct type **tqe_prev; /* address of previous next element */ \ struct type **tqe_prev; /* address of previous next element */ \
} }
/* /*
* tail queue access methods * tail queue access methods
*/ */
#define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL #define TAILQ_END(head) NULL
@ -430,7 +430,7 @@ struct { \
} }
/* /*
* Circular queue access methods * Circular queue access methods
*/ */
#define CIRCLEQ_FIRST(head) ((head)->cqh_first) #define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last) #define CIRCLEQ_LAST(head) ((head)->cqh_last)

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 /* Project : miniupnp
* Author : Thomas BERNARD * Author : Thomas BERNARD
* copyright (c) 2005-2008 Thomas Bernard * copyright (c) 2005-2011 Thomas Bernard
* This software is subjet to the conditions detailed in the * This software is subjet to the conditions detailed in the
* provided LICENCE file. */ * provided LICENCE file. */
#ifndef __CODELENGTH_H__ #ifndef __CODELENGTH_H__
@ -12,7 +12,14 @@
* following byte is part of the code */ * following byte is part of the code */
#define DECODELENGTH(n, p) n = 0; \ #define DECODELENGTH(n, p) n = 0; \
do { n = (n << 7) | (*p & 0x7f); } \ do { n = (n << 7) | (*p & 0x7f); } \
while(*(p++)&0x80); while((*(p++)&0x80) && (n<(1<<25)));
#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
n = 0; \
do { \
if((p) >= (p_limit)) break; \
n = (n << 7) | (*(p) & 0x7f); \
} while((*((p)++)&0x80) && (n<(1<<25)));
#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ #define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ if(n>=2097152) *(p++) = (n >> 21) | 0x80; \

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 /* Project: miniupnp
* http://miniupnp.free.fr/ * http://miniupnp.free.fr/
* Author: Thomas Bernard * Author: Thomas Bernard
* Copyright (c) 2010 Thomas Bernard * Copyright (c) 2010-2012 Thomas Bernard
* This software is subjects to the conditions detailed * This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */ * in the LICENCE file provided within this distribution */
#ifndef __CONNECTHOSTPORT_H__ #ifndef __CONNECTHOSTPORT_H__
@ -11,7 +11,8 @@
/* connecthostport() /* connecthostport()
* return a socket connected (TCP) to the host and port * return a socket connected (TCP) to the host and port
* or -1 in case of error */ * or -1 in case of error */
int connecthostport(const char * host, unsigned short port); int connecthostport(const char * host, unsigned short port,
unsigned int scope_id);
#endif #endif

View File

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

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 /* Project: miniupnp
* http://miniupnp.free.fr/ * http://miniupnp.free.fr/
* Author: Thomas Bernard * Author: Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard * Copyright (c) 2005-2012 Thomas Bernard
* This software is subjects to the conditions detailed * This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */ * in the LICENCE file provided within this distribution */
#ifndef __MINIUPNPC_H__ #ifndef __MINIUPNPC_H__
#define __MINIUPNPC_H__ #define __MINIUPNPC_H__
//#define MEGAGLEST_EMBEDDED_MINIUPNPC
//#define MINIUPNPC_VERSION_PRE1_5
//#define MINIUPNPC_VERSION_PRE1_6
#include "declspec.h" #include "declspec.h"
#include "igd_desc_parse.h" #include "igd_desc_parse.h"
@ -21,6 +17,10 @@
#define UPNPDISCOVER_SOCKET_ERROR (-101) #define UPNPDISCOVER_SOCKET_ERROR (-101)
#define UPNPDISCOVER_MEMORY_ERROR (-102) #define UPNPDISCOVER_MEMORY_ERROR (-102)
/* versions : */
#define MINIUPNPC_VERSION "1.7.20120830"
#define MINIUPNPC_API_VERSION 9
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -37,6 +37,7 @@ struct UPNPDev {
struct UPNPDev * pNext; struct UPNPDev * pNext;
char * descURL; char * descURL;
char * st; char * st;
unsigned int scope_id;
char buffer[2]; char buffer[2];
}; };
@ -78,6 +79,7 @@ struct UPNPUrls {
char * ipcondescURL; char * ipcondescURL;
char * controlURL_CIF; char * controlURL_CIF;
char * controlURL_6FC; char * controlURL_6FC;
char * rootdescURL;
}; };
/* UPNP_GetValidIGD() : /* UPNP_GetValidIGD() :
@ -109,9 +111,12 @@ UPNP_GetIGDFromUrl(const char * rootdescurl,
struct IGDdatas * data, struct IGDdatas * data,
char * lanaddr, int lanaddrlen); char * lanaddr, int lanaddrlen);
LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *); LIBSPEC void
GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
const char *, unsigned int);
LIBSPEC void FreeUPNPUrls(struct UPNPUrls *); LIBSPEC void
FreeUPNPUrls(struct UPNPUrls *);
/* return 0 or 1 */ /* return 0 or 1 */
LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); 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 /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard * Copyright (c) 2005-2012 Thomas Bernard
* This software is subject to the conditions detailed in the * This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. * LICENCE file provided in this distribution.
* */ * */
@ -16,11 +16,11 @@ extern "C" {
LIBSPEC void * getHTTPResponse(int s, int * size); LIBSPEC void * getHTTPResponse(int s, int * size);
LIBSPEC void * miniwget(const char *, int *); LIBSPEC void * miniwget(const char *, int *, unsigned int);
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int); LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int);
int parseURL(const char *, char *, unsigned short *, char * *); int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
#ifdef __cplusplus #ifdef __cplusplus
} }

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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * 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 * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
#ifndef __PORTLISTINGPARSE_H__ #ifndef __PORTLISTINGPARSE_H__
@ -11,7 +11,7 @@
/* for the definition of UNSIGNED_INTEGER */ /* for the definition of UNSIGNED_INTEGER */
#include "miniupnpctypes.h" #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" #include "bsdqueue.h"
#else #else
#include <sys/queue.h> #include <sys/queue.h>
@ -37,7 +37,7 @@ typedef enum { PortMappingEltNone,
PortMappingEntry, NewRemoteHost, PortMappingEntry, NewRemoteHost,
NewExternalPort, NewProtocol, NewExternalPort, NewProtocol,
NewInternalPort, NewInternalClient, NewInternalPort, NewInternalClient,
NewEnabled, NewDescription, NewEnabled, NewDescription,
NewLeaseTime } portMappingElt; NewLeaseTime } portMappingElt;
struct PortMapping { 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 /* 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) 2011 Thomas Bernard * Copyright (c) 2011-2012 Thomas Bernard
* This software is subjects to the conditions detailed * This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */ * in the LICENCE file provided within this distribution */
#ifndef __RECEIVEDATA_H__ #ifndef __RECEIVEDATA_H__
#define __RECEIVEDATA_H__ #define __RECEIVEDATA_H__
/* Reads data from the specified socket. /* Reads data from the specified socket.
* Returns the number of bytes read if successful, zero if no bytes were * 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. */ * 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 #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/ /* Miniupnp project : http://miniupnp.free.fr/
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard * Copyright (c) 2005-2011 Thomas Bernard
@ -62,12 +62,12 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. /* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it. * if the third arg is not null the value is copied to it.
* at least 16 bytes must be available * at least 16 bytes must be available
* *
* Return values : * Return values :
* 0 : SUCCESS * 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error. * NON ZERO : ERROR Either an UPnP error code or an unknown error.
* *
* possible UPnP Errors : * possible UPnP Errors :
* 402 Invalid Args - See UPnP Device Architecture section on Control. * 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control. */ * 501 Action Failed - See UPnP Device Architecture section on Control. */
@ -95,7 +95,7 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
* Return values : * Return values :
* 0 : SUCCESS * 0 : SUCCESS
* NON ZERO : ERROR. Either an UPnP error code or an unknown error. * NON ZERO : ERROR. Either an UPnP error code or an unknown error.
* *
* List of possible UPnP errors for AddPortMapping : * List of possible UPnP errors for AddPortMapping :
* errorCode errorDescription (short) - Description (long) * errorCode errorDescription (short) - Description (long)
* 402 Invalid Args - See UPnP Device Architecture section on Control. * 402 Invalid Args - See UPnP Device Architecture section on Control.
@ -106,7 +106,7 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
* 718 ConflictInMappingEntry - The port mapping entry specified conflicts * 718 ConflictInMappingEntry - The port mapping entry specified conflicts
* with a mapping assigned previously to another client * with a mapping assigned previously to another client
* 724 SamePortValuesRequired - Internal and External port values * 724 SamePortValuesRequired - Internal and External port values
* must be the same * must be the same
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
* permanent lease times on port mappings * permanent lease times on port mappings
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
@ -221,11 +221,11 @@ UPNP_GetListOfPortMappings(const char * controlURL,
const char * numberOfPorts, const char * numberOfPorts,
struct PortMappingParserData * data); struct PortMappingParserData * data);
/* IGD:2, functions for service WANIPv6FirewallControl:1 */ /* IGD:2, functions for service WANIPv6FirewallControl:1 */
LIBSPEC int LIBSPEC int
UPNP_GetFirewallStatus(const char * controlURL, UPNP_GetFirewallStatus(const char * controlURL,
const char * servicetype, const char * servicetype,
int * firewallEnabled, int * firewallEnabled,
int * inboundPinholeAllowed); int * inboundPinholeAllowed);
LIBSPEC int 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 /* (c) 2007 Thomas Bernard
* All rights reserved. * All rights reserved.
* MiniUPnP Project. * MiniUPnP Project.
@ -15,7 +15,7 @@ extern "C" {
#endif #endif
/* strupnperror() /* strupnperror()
* Return a string description of the UPnP error code * Return a string description of the UPnP error code
* or NULL for undefinded errors */ * or NULL for undefinded errors */
LIBSPEC const char * strupnperror(int err); LIBSPEC const char * strupnperror(int err);

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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * 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 * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
#ifndef __UPNPREPLYPARSE_H__ #ifndef __UPNPREPLYPARSE_H__
#define __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" #include "bsdqueue.h"
#else #else
#include <sys/queue.h> #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. 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 VERSION 1.6 : released 2011/07/25
2011/07/25: 2011/07/25:
@ -236,7 +312,7 @@ VERSION 1.2 :
small modif to make Clang happy :) small modif to make Clang happy :)
2008/07/17: 2008/07/17:
#define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV... #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
2008/07/14: 2008/07/14:
include declspec.h in installation (to /usr/include/miniupnpc) include declspec.h in installation (to /usr/include/miniupnpc)
@ -258,7 +334,7 @@ VERSION 1.1 :
improved python module error/exception reporting. improved python module error/exception reporting.
2008/04/23: 2008/04/23:
Completely rewrite igd_desc_parse.c in order to be compatible with Completely rewrite igd_desc_parse.c in order to be compatible with
Linksys WAG200G Linksys WAG200G
Added testigddescparse Added testigddescparse
updated python module updated python module
@ -281,7 +357,7 @@ VERSION 1.0 :
improved make install :) improved make install :)
2007/12/22: 2007/12/22:
Adding upnperrors.c/h to provide a strupnperror() function Adding upnperrors.c/h to provide a strupnperror() function
used to translate UPnP error codes to string. used to translate UPnP error codes to string.
2007/12/19: 2007/12/19:

View File

@ -1,5 +1,5 @@
MiniUPnPc MiniUPnPc
Copyright (c) 2005-2011, 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

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 # MiniUPnP Project
# http://miniupnp.free.fr/ # 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 : # to install use :
# $ PREFIX=/tmp/dummylocation make install # $ PREFIX=/tmp/dummylocation make install
# or # or
# $ INSTALLPREFIX=/usr/local make install # $ INSTALLPREFIX=/usr/local make install
# or # or
# make install (will go to /usr/bin, /usr/lib, etc...) # make install (will go to /usr/bin, /usr/lib, etc...)
OS = $(shell uname -s) OS = $(shell uname -s)
VERSION = $(shell cat VERSION)
ifeq ($(OS), Darwin)
JARSUFFIX=mac
endif
ifeq ($(OS), Linux)
JARSUFFIX=linux
endif
CC ?= gcc CC ?= gcc
#AR = gar #AR = gar
#CFLAGS = -O -Wall -g -DDEBUG #CFLAGS = -O -g -DDEBUG
CFLAGS ?= -O -Wall -DNDEBUG -DMINIUPNPC_SET_SOCKET_TIMEOUT -Wstrict-prototypes 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 # -DNO_GETADDRINFO
INSTALL = install INSTALL = install
SH = /bin/sh SH = /bin/sh
JAVA = java JAVA = java
# see http://code.google.com/p/jnaerator/ # 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 #following libs are needed on Solaris
#LDLIBS=-lsocket -lnsl -lresolv #LDLIBS=-lsocket -lnsl -lresolv
# APIVERSION is used to build SONAME # APIVERSION is used to build SONAME
APIVERSION = 8 APIVERSION = 9
SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \ SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \
upnpc.c upnpcommands.c upnpreplyparse.c testminixml.c \ upnpc.c upnpcommands.c upnpreplyparse.c testminixml.c \
@ -54,7 +73,7 @@ ifeq ($(OS), Darwin)
SHAREDLIBRARY = libminiupnpc.dylib SHAREDLIBRARY = libminiupnpc.dylib
SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib
CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS) CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS)
else else
SHAREDLIBRARY = libminiupnpc.so SHAREDLIBRARY = libminiupnpc.so
SONAME = $(SHAREDLIBRARY).$(APIVERSION) SONAME = $(SHAREDLIBRARY).$(APIVERSION)
endif endif
@ -85,6 +104,7 @@ INSTALLPREFIX ?= $(PREFIX)/usr
INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc
INSTALLDIRLIB = $(INSTALLPREFIX)/lib INSTALLDIRLIB = $(INSTALLPREFIX)/lib
INSTALLDIRBIN = $(INSTALLPREFIX)/bin INSTALLDIRBIN = $(INSTALLPREFIX)/bin
INSTALLDIRMAN = $(INSTALLPREFIX)/share/man
FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES) FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES)
ifneq ($(OS), AmigaOS) ifneq ($(OS), AmigaOS)
@ -92,12 +112,14 @@ FILESTOINSTALL := $(FILESTOINSTALL) $(SHAREDLIBRARY)
endif endif
.PHONY: install clean depend all check everything \ .PHONY: install clean depend all check test everything \
installpythonmodule installpythonmodule updateversion
# validateminixml validateminiwget # validateminixml validateminiwget
all: $(LIBRARY) $(EXECUTABLES) all: $(LIBRARY) $(EXECUTABLES)
test: check
check: validateminixml validateminiwget check: validateminixml validateminiwget
everything: all $(EXECUTABLES_ADDTESTS) everything: all $(EXECUTABLES_ADDTESTS)
@ -109,6 +131,13 @@ pythonmodule: $(LIBRARY) miniupnpcmodule.c setup.py
installpythonmodule: pythonmodule installpythonmodule: pythonmodule
python setup.py install python setup.py install
pythonmodule3: $(LIBRARY) miniupnpcmodule.c setup.py
python3 setup.py build
touch $@
installpythonmodule3: pythonmodule3
python3 setup.py install
validateminixml: minixmlvalid validateminixml: minixmlvalid
@echo "minixml validation test" @echo "minixml validation test"
./minixmlvalid ./minixmlvalid
@ -122,11 +151,17 @@ validateminiwget: testminiwget minihttptestserver testminiwget.sh
clean: clean:
$(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h $(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h
# clean python stuff # clean python stuff
$(RM) pythonmodule validateminixml $(RM) pythonmodule pythonmodule3 validateminixml validateminiwget
$(RM) -r build/ dist/ $(RM) -r build/ dist/
#python setup.py clean #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) -d $(INSTALLDIRINC)
$(INSTALL) -m 644 $(HEADERS) $(INSTALLDIRINC) $(INSTALL) -m 644 $(HEADERS) $(INSTALLDIRINC)
$(INSTALL) -d $(INSTALLDIRLIB) $(INSTALL) -d $(INSTALLDIRLIB)
@ -142,6 +177,11 @@ else
$(INSTALL) -m 755 upnpc-shared $(INSTALLDIRBIN)/upnpc $(INSTALL) -m 755 upnpc-shared $(INSTALLDIRBIN)/upnpc
endif endif
$(INSTALL) -m 755 external-ip.sh $(INSTALLDIRBIN)/external-ip $(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: cleaninstall:
$(RM) -r $(INSTALLDIRINC) $(RM) -r $(INSTALLDIRINC)
@ -156,7 +196,8 @@ $(LIBRARY): $(LIBOBJS)
$(SHAREDLIBRARY): $(LIBOBJS) $(SHAREDLIBRARY): $(LIBOBJS)
ifeq ($(OS), Darwin) 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 else
$(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^ $(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^
endif endif
@ -177,11 +218,47 @@ testupnpreplyparse: $(TESTUPNPREPLYPARSE)
testigddescparse: $(TESTIGDDESCPARSE) testigddescparse: $(TESTIGDDESCPARSE)
miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh VERSION
$(SH) updateminiupnpcstrings.sh $(SH) updateminiupnpcstrings.sh
jar: $(SHAREDLIBRARY) jnaerator-0.9.8-shaded.jar:
$(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 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 minihttptestserver: minihttptestserver.o

View File

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

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

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 /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2009 Thomas Bernard * Copyright (c) 2005-2012 Thomas Bernard
* This software is subject to the conditions detailed in the * This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. * LICENCE file provided in this distribution.
* *
@ -9,7 +9,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
#include <winsock2.h> #include <winsock2.h>
#define snprintf _snprintf #define snprintf _snprintf
@ -24,7 +24,7 @@
/* only for malloc */ /* only for malloc */
#include <stdlib.h> #include <stdlib.h>
#ifdef WIN32 #ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else #else
#define PRINT_SOCKET_ERROR(x) perror(x) #define PRINT_SOCKET_ERROR(x) perror(x)
@ -57,7 +57,7 @@ httpWrite(int fd, const char * body, int bodysize,
/* disable send on the socket */ /* disable send on the socket */
/* draytek routers dont seems to like that... */ /* draytek routers dont seems to like that... */
#if 0 #if 0
#ifdef WIN32 #ifdef _WIN32
if(shutdown(fd, SD_SEND)<0) { if(shutdown(fd, SD_SEND)<0) {
#else #else
if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/

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

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 /* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD * 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 * This software is subjet to the conditions detailed in the
* provided LICENSE file. */ * provided LICENSE file. */
#if defined(__APPLE__)
#define MACOSX 1
#define _DARWIN_C_SOURCE 1
#endif
#define __EXTENSIONS__ 1 #define __EXTENSIONS__ 1
#if !defined(MACOSX) && !defined(__sun) #if !defined(MACOSX) && !defined(__sun)
#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__) #if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__)
@ -21,10 +17,14 @@
#endif #endif
#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 <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef WIN32 #ifdef _WIN32
/* Win32 Specific includes and defines */ /* Win32 Specific includes and defines */
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
@ -39,7 +39,7 @@
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */ #endif /* #ifndef strncasecmp */
#define MAXHOSTNAMELEN 64 #define MAXHOSTNAMELEN 64
#else /* #ifdef WIN32 */ #else /* #ifdef _WIN32 */
/* Standard POSIX includes */ /* Standard POSIX includes */
#include <unistd.h> #include <unistd.h>
#if defined(__amigaos__) && !defined(__amigaos4__) #if defined(__amigaos__) && !defined(__amigaos4__)
@ -61,7 +61,7 @@
#include <strings.h> #include <strings.h>
#include <errno.h> #include <errno.h>
#define closesocket close #define closesocket close
#endif /* #else WIN32 */ #endif /* #else _WIN32 */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -79,7 +79,7 @@
#include "connecthostport.h" #include "connecthostport.h"
#include "receivedata.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());
#else #else
#define PRINT_SOCKET_ERROR(x) perror(x) #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", strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
soapbody + sizeof(soapbody) - p); soapbody + sizeof(soapbody) - p);
} }
if(!parseURL(url, hostname, &port, &path)) return NULL; if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
if(s<0) if(s < 0) {
{ s = connecthostport(hostname, port, 0);
s = connecthostport(hostname, port); if(s < 0) {
if(s < 0) /* failed to connect */
{
return NULL; return NULL;
} }
} }
@ -230,8 +229,9 @@ char * simpleUPnPcommand(int s, const char * url, const char * service,
{ {
char * buf; char * buf;
#if 1
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
/* #else
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0"); buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
if (!buf || *bufsize == 0) if (!buf || *bufsize == 0)
{ {
@ -240,7 +240,7 @@ char * simpleUPnPcommand(int s, const char * url, const char * service,
#endif #endif
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
} }
*/ #endif
return buf; return buf;
} }
@ -327,8 +327,9 @@ upnpDiscover(int delay, const char * multicastif,
{ {
struct UPNPDev * tmp; struct UPNPDev * tmp;
struct UPNPDev * devlist = 0; struct UPNPDev * devlist = 0;
unsigned int scope_id = 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: %s:" XSTR(PORT) "\r\n" "HOST: %s:" XSTR(PORT) "\r\n"
"ST: %s\r\n" "ST: %s\r\n"
@ -358,14 +359,14 @@ upnpDiscover(int delay, const char * multicastif,
int rv; int rv;
struct addrinfo hints, *servinfo, *p; struct addrinfo hints, *servinfo, *p;
#endif #endif
#ifdef WIN32 #ifdef _WIN32
MIB_IPFORWARDROW ip_forward; MIB_IPFORWARDROW ip_forward;
#endif #endif
int linklocal = 1; int linklocal = 1;
if(error) if(error)
*error = UPNPDISCOVER_UNKNOWN_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)
minissdpdsock = "/var/run/minissdpd.sock"; minissdpdsock = "/var/run/minissdpd.sock";
@ -383,7 +384,7 @@ upnpDiscover(int delay, const char * multicastif,
deviceIndex = 0; deviceIndex = 0;
#endif #endif
/* fallback to direct discovery */ /* fallback to direct discovery */
#ifdef WIN32 #ifdef _WIN32
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP); sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
#else #else
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0); 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_port = htons(PORT);
p->sin_addr.s_addr = INADDR_ANY; p->sin_addr.s_addr = INADDR_ANY;
} }
#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) */
@ -470,7 +471,7 @@ upnpDiscover(int delay, const char * multicastif,
} }
#endif #endif
#ifdef WIN32 #ifdef _WIN32
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
#else #else
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
@ -485,7 +486,7 @@ upnpDiscover(int delay, const char * multicastif,
if(multicastif) if(multicastif)
{ {
if(ipv6) { if(ipv6) {
#if !defined(WIN32) #if !defined(_WIN32)
/* according to MSDN, if_nametoindex() is supported since /* according to MSDN, if_nametoindex() is supported since
* MS Windows Vista and MS Windows Server 2008. * MS Windows Vista and MS Windows Server 2008.
* http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
@ -502,10 +503,28 @@ upnpDiscover(int delay, const char * multicastif,
} else { } else {
struct in_addr mc_if; struct in_addr mc_if;
mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ 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(mc_if.s_addr != INADDR_NONE)
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{ {
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 */ #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(ipv6 if ((rv = getaddrinfo(ipv6
@ -577,7 +596,7 @@ upnpDiscover(int delay, const char * multicastif,
XSTR(PORT), &hints, &servinfo)) != 0) { XSTR(PORT), &hints, &servinfo)) != 0) {
if(error) if(error)
*error = UPNPDISCOVER_SOCKET_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));
@ -586,13 +605,14 @@ upnpDiscover(int delay, const char * multicastif,
} }
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);
#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) { 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"); PRINT_SOCKET_ERROR("sendto");
continue; continue;
} }
@ -606,12 +626,7 @@ upnpDiscover(int delay, const char * multicastif,
#endif /* #ifdef NO_GETADDRINFO */ #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, &scope_id);
#ifdef DEBUG
printf("receivedata returned %d [%s]\n", n,bufr);
#endif
if (n < 0) { if (n < 0) {
/* error */ /* error */
if(error) if(error)
@ -671,6 +686,7 @@ upnpDiscover(int delay, const char * multicastif,
tmp->buffer[urlsize] = '\0'; tmp->buffer[urlsize] = '\0';
memcpy(tmp->buffer + urlsize + 1, st, stsize); memcpy(tmp->buffer + urlsize + 1, st, stsize);
tmp->buffer[urlsize+1+stsize] = '\0'; tmp->buffer[urlsize+1+stsize] = '\0';
tmp->scope_id = scope_id;
devlist = tmp; devlist = tmp;
} }
} }
@ -717,14 +733,31 @@ url_cpy_or_cat(char * dst, const char * src, int n)
/* Prepare the Urls for usage... /* Prepare the Urls for usage...
*/ */
LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, LIBSPEC void
const char * descURL) GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
const char * descURL, unsigned int scope_id)
{ {
char * p; char * p;
int n1, n2, n3, n4; int n1, n2, n3, n4;
#ifdef IF_NAMESIZE
char ifname[IF_NAMESIZE];
#else
char scope_str[8];
#endif
n1 = strlen(data->urlbase); n1 = strlen(data->urlbase);
if(n1==0) if(n1==0)
n1 = strlen(descURL); 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 */ n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
n2 = n1; n3 = n1; n4 = n1; n2 = n1; n3 = n1; n4 = n1;
n1 += strlen(data->first.scpdurl); n1 += strlen(data->first.scpdurl);
@ -732,21 +765,44 @@ LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
n3 += strlen(data->CIF.controlurl); n3 += strlen(data->CIF.controlurl);
n4 += strlen(data->IPv6FC.controlurl); n4 += strlen(data->IPv6FC.controlurl);
/* allocate memory to store URLs */
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); 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') if(data->urlbase[0] != '\0')
strncpy(urls->ipcondescURL, data->urlbase, n1); strncpy(urls->ipcondescURL, data->urlbase, n1);
else else
strncpy(urls->ipcondescURL, descURL, n1); strncpy(urls->ipcondescURL, descURL, n1);
p = strchr(urls->ipcondescURL+7, '/'); p = strchr(urls->ipcondescURL+7, '/');
if(p) p[0] = '\0'; 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, urls->ipcondescURL, n2);
strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3); strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4); 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);
url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2); url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2);
@ -780,6 +836,8 @@ FreeUPNPUrls(struct UPNPUrls * urls)
urls->controlURL_CIF = 0; urls->controlURL_CIF = 0;
free(urls->controlURL_6FC); free(urls->controlURL_6FC);
urls->controlURL_6FC = 0; urls->controlURL_6FC = 0;
free(urls->rootdescURL);
urls->rootdescURL = 0;
} }
int int
@ -801,6 +859,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
/* UPNP_GetValidIGD() : /* UPNP_GetValidIGD() :
* return values : * return values :
* -1 = Internal error
* 0 = NO IGD found * 0 = NO IGD found
* 1 = A valid connected IGD has been found * 1 = A valid connected IGD has been found
* 2 = A valid IGD has been found but it reported as * 2 = A valid IGD has been found but it reported as
@ -817,11 +876,14 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
struct IGDdatas * data, struct IGDdatas * data,
char * lanaddr, int lanaddrlen) char * lanaddr, int lanaddrlen)
{ {
char * descXML; struct xml_desc {
int descXMLsize = 0; char * xml;
int size;
} * desc = NULL;
struct UPNPDev * dev; struct UPNPDev * dev;
int ndev = 0; 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) if(!devlist)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -829,27 +891,42 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
#endif #endif
return 0; 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(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. /* we should choose an internet gateway device.
* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
descXML = miniwget_getaddr(dev->descURL, &descXMLsize, if(state == 1)
lanaddr, lanaddrlen); {
if(descXML) 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(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls)); memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data); parserootdesc(desc[i].xml, desc[i].size, data);
free(descXML);
descXML = NULL;
if(0==strcmp(data->CIF.servicetype, if(0==strcmp(data->CIF.servicetype,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1") "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
|| state >= 3 ) || state >= 3 )
{ {
GetUPNPUrls(urls, data, dev->descURL); GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
#ifdef DEBUG #ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n", printf("UPNPIGD_IsConnected(%s) = %d\n",
@ -857,7 +934,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
UPNPIGD_IsConnected(urls, data)); UPNPIGD_IsConnected(urls, data));
#endif #endif
if((state >= 2) || UPNPIGD_IsConnected(urls, data)) if((state >= 2) || UPNPIGD_IsConnected(urls, data))
return state; goto free_and_return;
FreeUPNPUrls(urls); FreeUPNPUrls(urls);
if(data->second.servicetype[0] != '\0') { if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG #ifdef DEBUG
@ -868,28 +945,32 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
memcpy(&data->second, &data->tmp, 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 #ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n", printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, urls->controlURL,
UPNPIGD_IsConnected(urls, data)); UPNPIGD_IsConnected(urls, data));
#endif #endif
if((state >= 2) || UPNPIGD_IsConnected(urls, data)) if((state >= 2) || UPNPIGD_IsConnected(urls, data))
return state; goto free_and_return;
FreeUPNPUrls(urls); FreeUPNPUrls(urls);
} }
} }
memset(data, 0, sizeof(struct IGDdatas)); 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() /* UPNP_GetIGDFromUrl()
@ -906,14 +987,14 @@ UPNP_GetIGDFromUrl(const char * rootdescurl,
char * descXML; char * descXML;
int descXMLsize = 0; int descXMLsize = 0;
descXML = miniwget_getaddr(rootdescurl, &descXMLsize, descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
lanaddr, lanaddrlen); lanaddr, lanaddrlen, 0);
if(descXML) { if(descXML) {
memset(data, 0, sizeof(struct IGDdatas)); memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls)); memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data); parserootdesc(descXML, descXMLsize, data);
free(descXML); free(descXML);
descXML = NULL; descXML = NULL;
GetUPNPUrls(urls, data, rootdescurl); GetUPNPUrls(urls, data, rootdescurl, 0);
return 1; return 1;
} else { } else {
return 0; 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 /* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard * 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 * This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */ * LICENCE file provided in this distribution. */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#ifdef WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <io.h> #include <io.h>
@ -24,7 +25,7 @@
#define strncasecmp memicmp #define strncasecmp memicmp
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */ #endif /* #ifndef strncasecmp */
#else /* #ifdef WIN32 */ #else /* #ifdef _WIN32 */
#include <unistd.h> #include <unistd.h>
#include <sys/param.h> #include <sys/param.h>
#if defined(__amigaos__) && !defined(__amigaos4__) #if defined(__amigaos__) && !defined(__amigaos4__)
@ -33,13 +34,15 @@
#include <sys/select.h> #include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h> #include <netdb.h>
#define closesocket close #define closesocket close
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */ * during the connect() call */
#define MINIUPNPC_IGNORE_EINTR #define MINIUPNPC_IGNORE_EINTR
#endif /* #else WIN32 */ #endif /* #else _WIN32 */
#if defined(__sun) || defined(sun) #if defined(__sun) || defined(sun)
#define MIN(x,y) (((x)<(y))?(x):(y)) #define MIN(x,y) (((x)<(y))?(x):(y))
#endif #endif
@ -67,22 +70,20 @@ getHTTPResponse(int s, int * size)
unsigned int bytestocopy = 0; unsigned int bytestocopy = 0;
/* buffers : */ /* buffers : */
char * header_buf; char * header_buf;
int header_buf_len = 2048; unsigned int header_buf_len = 2048;
int header_buf_used = 0; unsigned int header_buf_used = 0;
char * content_buf; char * content_buf;
char *content_buf_new; unsigned int content_buf_len = 2048;
int content_buf_len = 2048; unsigned int content_buf_used = 0;
int content_buf_used = 0;
char chunksize_buf[32]; char chunksize_buf[32];
int chunksize_buf_index; unsigned int chunksize_buf_index;
header_buf = malloc(header_buf_len); header_buf = malloc(header_buf_len);
header_buf[0] = '\0';
content_buf = malloc(content_buf_len); content_buf = malloc(content_buf_len);
chunksize_buf[0] = '\0'; chunksize_buf[0] = '\0';
chunksize_buf_index = 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) if(endofheaders == 0)
{ {
@ -91,25 +92,22 @@ getHTTPResponse(int s, int * size)
int colon=0; int colon=0;
int valuestart=0; int valuestart=0;
if(header_buf_used + n > header_buf_len) { if(header_buf_used + n > header_buf_len) {
char *header_buf_new = realloc(header_buf, header_buf_used + n); header_buf = realloc(header_buf, header_buf_used + n);
if(header_buf_new != NULL) { header_buf_len = header_buf_used + n;
header_buf = header_buf_new;
header_buf_len = header_buf_used + n;
}
} }
memcpy(header_buf + header_buf_used, buf, n); memcpy(header_buf + header_buf_used, buf, n);
header_buf_used += n; header_buf_used += n;
/* search for CR LF CR LF (end of headers) /* search for CR LF CR LF (end of headers)
* recognize also LF LF */ * recognize also LF LF */
i = 0; i = 0;
while(i < (header_buf_used-1) && (endofheaders == 0)) { while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
if(header_buf[i] == '\r') { if(header_buf[i] == '\r') {
i++; i++;
if(header_buf[i] == '\n') { if(header_buf[i] == '\n') {
i++; i++;
if(i < header_buf_used && header_buf[i] == '\r') { if(i < (int)header_buf_used && header_buf[i] == '\r') {
i++; i++;
if(i < header_buf_used && header_buf[i] == '\n') { if(i < (int)header_buf_used && header_buf[i] == '\n') {
endofheaders = i+1; endofheaders = i+1;
} }
} }
@ -165,7 +163,7 @@ getHTTPResponse(int s, int * size)
linestart = i; linestart = i;
colon = linestart; colon = linestart;
valuestart = 0; valuestart = 0;
} }
} }
/* copy the remaining of the received data back to buf */ /* copy the remaining of the received data back to buf */
n = header_buf_used - endofheaders; n = header_buf_used - endofheaders;
@ -199,7 +197,7 @@ getHTTPResponse(int s, int * size)
i++; /* discarding chunk-extension */ i++; /* discarding chunk-extension */
if(i<n && buf[i] == '\r') i++; if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') { if(i<n && buf[i] == '\n') {
int j; unsigned int j;
for(j = 0; j < chunksize_buf_index; j++) { for(j = 0; j < chunksize_buf_index; j++) {
if(chunksize_buf[j] >= '0' if(chunksize_buf[j] >= '0'
&& chunksize_buf[j] <= '9') && chunksize_buf[j] <= '9')
@ -226,20 +224,16 @@ getHTTPResponse(int s, int * size)
goto end_of_stream; goto end_of_stream;
} }
} }
bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i); bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
if((int)(content_buf_used + bytestocopy) > content_buf_len) if((content_buf_used + bytestocopy) > content_buf_len)
{ {
if(content_length >= content_buf_used + (int)bytestocopy) { if(content_length >= (int)(content_buf_used + bytestocopy)) {
content_buf_len = content_length; content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + bytestocopy;
} }
else { content_buf = (char *)realloc((void *)content_buf,
content_buf_len = content_buf_used + (int)bytestocopy;
}
content_buf_new = (char *)realloc((void *)content_buf,
content_buf_len); content_buf_len);
if(content_buf_new) {
content_buf = content_buf_new;
}
} }
memcpy(content_buf + content_buf_used, buf + i, bytestocopy); memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
content_buf_used += bytestocopy; content_buf_used += bytestocopy;
@ -251,29 +245,26 @@ getHTTPResponse(int s, int * size)
{ {
/* not chunked */ /* not chunked */
if(content_length > 0 if(content_length > 0
&& (content_buf_used + n) > content_length) { && (int)(content_buf_used + n) > content_length) {
/* skipping additional bytes */ /* skipping additional bytes */
n = content_length - content_buf_used; n = content_length - content_buf_used;
} }
if(content_buf_used + n > content_buf_len) 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; content_buf_len = content_length;
} else { } else {
content_buf_len = content_buf_used + n; 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); content_buf_len);
if(content_buf_new) {
content_buf = content_buf_new;
}
} }
memcpy(content_buf + content_buf_used, buf, n); memcpy(content_buf + content_buf_used, buf, n);
content_buf_used += n; content_buf_used += n;
} }
} }
/* use the Content-Length header value if available */ /* 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 #ifdef DEBUG
printf("End of HTTP content\n"); printf("End of HTTP content\n");
@ -296,10 +287,10 @@ end_of_stream:
* do all the work. * do all the work.
* Return NULL if something failed. */ * Return NULL if something failed. */
static void * static void *
miniwget3(const char * url, const char * host, miniwget3(const char * host,
unsigned short port, const char * path, unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len, int * size, char * addr_str, int addr_str_len,
const char * httpversion) const char * httpversion, unsigned int scope_id)
{ {
char buf[2048]; char buf[2048];
int s; int s;
@ -309,7 +300,7 @@ miniwget3(const char * url, const char * host,
void * content; void * content;
*size = 0; *size = 0;
s = connecthostport(host, port); s = connecthostport(host, port, scope_id);
if(s < 0) if(s < 0)
return NULL; return NULL;
@ -355,7 +346,7 @@ miniwget3(const char * url, const char * host,
NULL, 0, NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV); NI_NUMERICHOST | NI_NUMERICSERV);
if(n != 0) { if(n != 0) {
#ifdef WIN32 #ifdef _WIN32
fprintf(stderr, "getnameinfo() failed : %d\n", n); fprintf(stderr, "getnameinfo() failed : %d\n", n);
#else #else
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
@ -400,24 +391,29 @@ miniwget3(const char * url, const char * host,
/* miniwget2() : /* miniwget2() :
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
static void * static void *
miniwget2(const char * url, const char * host, miniwget2(const char * host,
unsigned short port, const char * path, unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len) int * size, char * addr_str, int addr_str_len,
unsigned int scope_id)
{ {
char * respbuffer; char * respbuffer;
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1"); #if 1
/* respbuffer = miniwget3(host, port, path, size,
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0"); addr_str, addr_str_len, "1.1", scope_id);
#else
respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.0", scope_id);
if (*size == 0) if (*size == 0)
{ {
#ifdef DEBUG #ifdef DEBUG
printf("Retrying with HTTP/1.1\n"); printf("Retrying with HTTP/1.1\n");
#endif #endif
free(respbuffer); free(respbuffer);
respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1"); respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1", scope_id);
} }
*/ #endif
return respbuffer; return respbuffer;
} }
@ -429,12 +425,15 @@ miniwget2(const char * url, const char * host,
* url : source string not modified * url : source string not modified
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1) * hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
* port : port (destination) * port : port (destination)
* path : pointer to the path part of the URL * path : pointer to the path part of the URL
* *
* Return values : * Return values :
* 0 - Failure * 0 - Failure
* 1 - Success */ * 1 - Success */
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path) int
parseURL(const char * url,
char * hostname, unsigned short * port,
char * * path, unsigned int * scope_id)
{ {
char * p1, *p2, *p3; char * p1, *p2, *p3;
if(!url) if(!url)
@ -450,7 +449,43 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
if(*p1 == '[') if(*p1 == '[')
{ {
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
char * scope;
scope = strchr(p1, '%');
p2 = 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, '/'); p3 = strchr(p1, '/');
if(p2 && p3) if(p2 && p3)
{ {
@ -500,35 +535,40 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
return 1; return 1;
} }
void * miniwget(const char * url, int * size) void *
miniwget(const char * url, int * size, unsigned int scope_id)
{ {
unsigned short port; unsigned short port;
char * path; char * path;
/* protocol://host:port/chemin */ /* protocol://host:port/chemin */
char hostname[MAXHOSTNAMELEN+1]; char hostname[MAXHOSTNAMELEN+1];
*size = 0; *size = 0;
if(!parseURL(url, hostname, &port, &path)) if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL; return NULL;
#ifdef DEBUG #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 #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; unsigned short port;
char * path; char * path;
/* protocol://host:port/chemin */ /* protocol://host:port/path */
char hostname[MAXHOSTNAMELEN+1]; char hostname[MAXHOSTNAMELEN+1];
*size = 0; *size = 0;
if(addr) if(addr)
addr[0] = '\0'; addr[0] = '\0';
if(!parseURL(url, hostname, &port, &path)) if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL; return NULL;
#ifdef DEBUG #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 #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 ! */ /* 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-2011, 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
@ -149,7 +149,7 @@ static void parseelt(struct xmlparser * p)
return; return;
} }
if(memcmp(p->xml, "<![CDATA[", 9) == 0) if(memcmp(p->xml, "<![CDATA[", 9) == 0)
{ {
/* CDATA handling */ /* CDATA handling */
p->xml += 9; p->xml += 9;
data = p->xml; 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 /* MiniUPnP Project
* http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
* minixmlvalid.c : * minixmlvalid.c :
@ -32,7 +32,7 @@ int evtlistcmp(struct eventlist * a, struct eventlist * b)
if(a->n != b->n) if(a->n != b->n)
{ {
printf("event number not matching : %d != %d\n", 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++) for(i=0; i<a->n; i++)
{ {
@ -82,7 +82,7 @@ static const struct event evtref[] =
{ELTEND, "elt2b", 5}, {ELTEND, "elt2b", 5},
{ELTEND, "elt2a", 5}, {ELTEND, "elt2a", 5},
{ELTEND, "xmlroot", 7} {ELTEND, "xmlroot", 7}
}; };
void startelt(void * data, const char * p, int l) 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 main(int argc, char * * argv)
{ {
int r; int r;
(void)argc; (void)argv;
r = testxmlparser(xmldata, sizeof(xmldata)-1); r = testxmlparser(xmldata, sizeof(xmldata)-1);
if(r) if(r)
printf("minixml validation test failed\n"); 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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * 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 * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
#include <string.h> #include <string.h>
@ -71,6 +71,8 @@ static void
endelt(void * d, const char * name, int l) endelt(void * d, const char * name, int l)
{ {
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
(void)name;
(void)l;
pdata->curelt = PortMappingEltNone; 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 /* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2011 Thomas Bernard * Copyright (c) 2011-2012 Thomas Bernard
* This software is subject to the conditions detailed in the * This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */ * LICENCE file provided in this distribution. */
#include <stdio.h> #include <stdio.h>
#ifdef WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#else #else
@ -17,6 +18,7 @@
#include <sys/select.h> #include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h>
#if !defined(__amigaos__) && !defined(__amigaos4__) #if !defined(__amigaos__) && !defined(__amigaos4__)
#include <poll.h> #include <poll.h>
#endif #endif
@ -24,7 +26,7 @@
#define MINIUPNPC_IGNORE_EINTR #define MINIUPNPC_IGNORE_EINTR
#endif #endif
#ifdef WIN32 #ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else #else
#define PRINT_SOCKET_ERROR(x) perror(x) #define PRINT_SOCKET_ERROR(x) perror(x)
@ -33,10 +35,16 @@
#include "receivedata.h" #include "receivedata.h"
int 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; int n;
#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) #if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
/* using poll */ /* using poll */
struct pollfd fds[1]; /* for the poll */ struct pollfd fds[1]; /* for the poll */
#ifdef MINIUPNPC_IGNORE_EINTR #ifdef MINIUPNPC_IGNORE_EINTR
@ -55,8 +63,8 @@ receivedata(int socket, char * data, int length, int timeout)
/* timeout */ /* timeout */
return 0; return 0;
} }
#else /* !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ #else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
/* using select under WIN32 and amigaos */ /* using select under _WIN32 and amigaos */
fd_set socketSet; fd_set socketSet;
TIMEVAL timeval; TIMEVAL timeval;
FD_ZERO(&socketSet); FD_ZERO(&socketSet);
@ -69,12 +77,27 @@ receivedata(int socket, char * data, int length, int timeout)
return -1; return -1;
} else if(n == 0) { } else if(n == 0) {
return 0; return 0;
} }
#endif #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); n = recv(socket, data, length, 0);
#endif
if(n<0) { if(n<0) {
PRINT_SOCKET_ERROR("recv"); 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; return n;
} }

View File

@ -1,13 +1,16 @@
#! /usr/bin/python #! /usr/bin/python
# $Id: setup.py,v 1.6 2011/01/04 09:46:08 nanard Exp $ # $Id: setup.py,v 1.9 2012/05/23 08:50:10 nanard Exp $
# the MiniUPnP Project (c) 2007-2011 Thomas Bernard # the MiniUPnP Project (c) 2007-2012 Thomas Bernard
# http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ # http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
# #
# python script to build the miniupnpc module under unix # python script to build the miniupnpc module under unix
# #
# replace libminiupnpc.a by libminiupnpc.so for shared library usage # replace libminiupnpc.a by libminiupnpc.so for shared library usage
from distutils.core import setup, Extension 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=[ ext_modules=[
Extension(name="miniupnpc", sources=["miniupnpcmodule.c"], Extension(name="miniupnpc", sources=["miniupnpcmodule.c"],
extra_objects=["libminiupnpc.a"]) extra_objects=["libminiupnpc.a"])

View File

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

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/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/ # project miniupnp : http://miniupnp.free.fr/
# (c) 2011 Thomas Bernard # (c) 2011-2012 Thomas Bernard
# #
# test program for miniwget.c # test program for miniwget.c
# is usually invoked by "make check" # is usually invoked by "make check"
@ -12,10 +12,13 @@
# 3 - compares served and received data # 3 - compares served and received data
# 4 - kills the local HTTP server and exits # 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 TMPDIR=`mktemp -d`
EXPECTEDFILE=/tmp/expectedfile HTTPSERVEROUT="${TMPDIR}/httpserverout"
DOWNLOADEDFILE=/tmp/downloadedfile EXPECTEDFILE="${TMPDIR}/expectedfile"
DOWNLOADEDFILE="${TMPDIR}/downloadedfile"
#ADDR=localhost #ADDR=localhost
ADDR="[::1]" ADDR="[::1]"
PORT= PORT=
@ -26,7 +29,8 @@ RET=0
# launching the test HTTP server # launching the test HTTP server
./minihttptestserver -6 -e $EXPECTEDFILE > $HTTPSERVEROUT & ./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/' ` PORT=`cat $HTTPSERVEROUT | sed 's/Listening on port \([0-9]*\)/\1/' `
done done
echo "Test HTTP server is listening on $PORT" echo "Test HTTP server is listening on $PORT"
@ -72,8 +76,10 @@ if [ $RET -eq 0 ]; then
rm -f "${DOWNLOADEDFILE}.2" rm -f "${DOWNLOADEDFILE}.2"
rm -f "${DOWNLOADEDFILE}.3" rm -f "${DOWNLOADEDFILE}.3"
rm -f $EXPECTEDFILE $HTTPSERVEROUT rm -f $EXPECTEDFILE $HTTPSERVEROUT
rmdir ${TMPDIR}
else else
echo "at least one of the test FAILED" echo "at least one of the test FAILED"
echo "directory ${TMPDIR} is left intact"
fi fi
exit $RET 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 /* Project : miniupnp
* Author : Thomas Bernard * 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 * This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */ * LICENCE file provided in this distribution. */
@ -9,16 +9,19 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#ifdef WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
#define snprintf _snprintf #define snprintf _snprintf
#else
/* for IPPROTO_TCP / IPPROTO_UDP */
#include <netinet/in.h>
#endif #endif
#include "miniwget.h" #include "miniwget.h"
#include "miniupnpc.h" #include "miniupnpc.h"
#include "upnpcommands.h" #include "upnpcommands.h"
#include "upnperrors.h" #include "upnperrors.h"
/* protofix() checks if protocol is "UDP" or "TCP" /* protofix() checks if protocol is "UDP" or "TCP"
* returns NULL if not */ * returns NULL if not */
const char * protofix(const char * proto) 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}; static const char proto_udp[4] = { 'U', 'D', 'P', 0};
int i, b; int i, b;
for(i=0, b=1; i<4; i++) 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)) ); || (proto[i] == (proto_tcp[i] | 32)) );
if(b) if(b)
return proto_tcp; return proto_tcp;
@ -49,44 +52,47 @@ static void DisplayInfos(struct UPNPUrls * urls,
unsigned int brUp, brDown; unsigned int brUp, brDown;
time_t timenow, timestarted; time_t timenow, timestarted;
int r; int r;
UPNP_GetConnectionTypeInfo(urls->controlURL, if(UPNP_GetConnectionTypeInfo(urls->controlURL,
data->first.servicetype, data->first.servicetype,
connectionType); connectionType) != UPNPCOMMAND_SUCCESS)
if(connectionType[0])
printf("Connection Type : %s\n", connectionType);
else
printf("GetConnectionTypeInfo failed.\n"); printf("GetConnectionTypeInfo failed.\n");
UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, else
status, &uptime, lastconnerr); printf("Connection Type : %s\n", connectionType);
printf("Status : %s, uptime=%us, LastConnectionError : %s\n", if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
status, uptime, lastconnerr); status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS)
printf("GetStatusInfo failed.\n");
else
printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
status, uptime, lastconnerr);
timenow = time(NULL); timenow = time(NULL);
timestarted = timenow - uptime; timestarted = timenow - uptime;
printf(" Time started : %s", ctime(&timestarted)); printf(" Time started : %s", ctime(&timestarted));
UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
&brDown, &brUp); &brDown, &brUp) != UPNPCOMMAND_SUCCESS) {
printf("MaxBitRateDown : %u bps", brDown); printf("GetLinkLayerMaxBitRates failed.\n");
if(brDown >= 1000000) { } else {
printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); printf("MaxBitRateDown : %u bps", brDown);
} else if(brDown >= 1000) { if(brDown >= 1000000) {
printf(" (%u Kbps)", brDown / 1000); 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, r = UPNP_GetExternalIPAddress(urls->controlURL,
data->first.servicetype, data->first.servicetype,
externalIPAddress); externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS) if(r != UPNPCOMMAND_SUCCESS) {
printf("GetExternalIPAddress() returned %d\n", r); printf("GetExternalIPAddress failed. (errorcode=%d)\n", r);
if(externalIPAddress[0]) } else {
printf("ExternalIPAddress = %s\n", externalIPAddress); printf("ExternalIPAddress = %s\n", externalIPAddress);
else }
printf("GetExternalIPAddress failed.\n");
} }
static void GetConnectionStatus(struct UPNPUrls * urls, static void GetConnectionStatus(struct UPNPUrls * urls,
@ -119,6 +125,7 @@ static void ListRedirections(struct UPNPUrls * urls,
/*unsigned int num=0; /*unsigned int num=0;
UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
printf("PortMappingNumberOfEntries : %u\n", num);*/ printf("PortMappingNumberOfEntries : %u\n", num);*/
printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
do { do {
snprintf(index, 6, "%d", i); snprintf(index, 6, "%d", i);
rHost[0] = '\0'; enabled[0] = '\0'; rHost[0] = '\0'; enabled[0] = '\0';
@ -166,6 +173,7 @@ static void NewListRedirections(struct UPNPUrls * urls,
&pdata); &pdata);
if(r == UPNPCOMMAND_SUCCESS) 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) for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
{ {
printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", 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 * 1 - get connection type
* 2 - get extenal ip address * 2 - get extenal ip address
* 3 - Add port mapping * 3 - Add port mapping
@ -239,7 +247,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
fprintf(stderr, "invalid protocol\n"); fprintf(stderr, "invalid protocol\n");
return; return;
} }
UPNP_GetExternalIPAddress(urls->controlURL, UPNP_GetExternalIPAddress(urls->controlURL,
data->first.servicetype, data->first.servicetype,
externalIPAddress); externalIPAddress);
@ -247,7 +255,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
printf("ExternalIPAddress = %s\n", externalIPAddress); printf("ExternalIPAddress = %s\n", externalIPAddress);
else else
printf("GetExternalIPAddress failed.\n"); printf("GetExternalIPAddress failed.\n");
r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
eport, iport, iaddr, 0, proto, 0, leaseDuration); eport, iport, iaddr, 0, proto, 0, leaseDuration);
if(r!=UPNPCOMMAND_SUCCESS) if(r!=UPNPCOMMAND_SUCCESS)
@ -262,7 +270,7 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
if(r!=UPNPCOMMAND_SUCCESS) if(r!=UPNPCOMMAND_SUCCESS)
printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
r, strupnperror(r)); r, strupnperror(r));
if(intClient[0]) { if(intClient[0]) {
printf("InternalIP:Port = %s:%s\n", intClient, intPort); printf("InternalIP:Port = %s:%s\n", intClient, intPort);
printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", 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); UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed);
printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", 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"); 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); bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
packetssent = UPNP_GetTotalPacketsSent(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); printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
} }
/* Test function /* Test function
* 1 - Add pinhole * 1 - Add pinhole
* 2 - Check if pinhole is working from the IGD side */ * 2 - Check if pinhole is working from the IGD side */
static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, 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) const char * proto, const char * lease_time)
{ {
char uniqueID[8]; char uniqueID[8];
//int isWorking = 0; /*int isWorking = 0;*/
int r; int r;
char proto_tmp[8];
if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time)
{ {
fprintf(stderr, "Wrong arguments\n"); fprintf(stderr, "Wrong arguments\n");
return; return;
} }
/*proto = protofix(proto); if(atoi(proto) == 0)
if(!proto)
{ {
fprintf(stderr, "invalid protocol\n"); const char * protocol;
return; 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); r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID);
if(r!=UPNPCOMMAND_SUCCESS) if(r!=UPNPCOMMAND_SUCCESS)
printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", 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 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); /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking);
if(r!=UPNPCOMMAND_SUCCESS) if(r!=UPNPCOMMAND_SUCCESS)
printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); 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 * Get pinhole timeout
*/ */
static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data,
@ -464,7 +488,7 @@ int main(int argc, char ** argv)
int error = 0; int error = 0;
int ipv6 = 0; int ipv6 = 0;
#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)
@ -473,7 +497,7 @@ int main(int argc, char ** argv)
return -1; return -1;
} }
#endif #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" printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
"for more information.\n"); "for more information.\n");
/* command line processing */ /* command line processing */
@ -529,7 +553,7 @@ int main(int argc, char ** argv)
fprintf(stderr, "Options:\n"); fprintf(stderr, "Options:\n");
fprintf(stderr, " -6 : use ip v6 instead of ip v4.\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, " -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"); fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n");
return 1; return 1;
} }
@ -573,7 +597,6 @@ int main(int argc, char ** argv)
default: default:
printf("Found device (igd ?) : %s\n", urls.controlURL); printf("Found device (igd ?) : %s\n", urls.controlURL);
printf("Trying to continue anyway\n"); printf("Trying to continue anyway\n");
break;
} }
printf("Local LAN ip address : %s\n", lanaddr); printf("Local LAN ip address : %s\n", lanaddr);
#if 0 #if 0
@ -663,7 +686,6 @@ int main(int argc, char ** argv)
default: default:
fprintf(stderr, "Unknown switch -%c\n", command); fprintf(stderr, "Unknown switch -%c\n", command);
retcode = 1; retcode = 1;
break;
} }
FreeUPNPUrls(&urls); 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 /* Project : miniupnp
* Author : Thomas Bernard * 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 * This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. * LICENCE file provided in this distribution.
* */ * */
@ -119,7 +119,7 @@ UPNP_GetTotalPacketsReceived(const char * controlURL,
LIBSPEC int LIBSPEC int
UPNP_GetStatusInfo(const char * controlURL, UPNP_GetStatusInfo(const char * controlURL,
const char * servicetype, const char * servicetype,
char * status, char * status,
unsigned int * uptime, unsigned int * uptime,
char * lastconnerror) char * lastconnerror)
{ {
@ -221,8 +221,8 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. /* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
* One of the values can be null * One of the values can be null
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */ * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
LIBSPEC int LIBSPEC int
UPNP_GetLinkLayerMaxBitRates(const char * controlURL, UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
@ -285,7 +285,7 @@ UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. /* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it. * if the third arg is not null the value is copied to it.
* at least 16 bytes must be available * at least 16 bytes must be available
* *
* Return values : * Return values :
* 0 : SUCCESS * 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error. * NON ZERO : ERROR Either an UPnP error code or an unknown error.
@ -741,16 +741,16 @@ UPNP_GetListOfPortMappings(const char * controlURL,
} }
ClearNameValueList(&pdata); ClearNameValueList(&pdata);
//printf("%.*s", bufsize, buffer); /*printf("%.*s", bufsize, buffer);*/
return ret; return ret;
} }
/* IGD:2, functions for service WANIPv6FirewallControl:1 */ /* IGD:2, functions for service WANIPv6FirewallControl:1 */
LIBSPEC int LIBSPEC int
UPNP_GetFirewallStatus(const char * controlURL, UPNP_GetFirewallStatus(const char * controlURL,
const char * servicetype, const char * servicetype,
int * firewallEnabled, int * firewallEnabled,
int * inboundPinholeAllowed) int * inboundPinholeAllowed)
{ {
struct NameValueParserData pdata; struct NameValueParserData pdata;
@ -868,7 +868,7 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype,
return UPNPCOMMAND_INVALID_ARGS; return UPNPCOMMAND_INVALID_ARGS;
AddPinholeArgs = calloc(7, sizeof(struct UPNParg)); AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
// RemoteHost can be wilcarded /* RemoteHost can be wilcarded */
if(strncmp(remoteHost, "empty", 5)==0) if(strncmp(remoteHost, "empty", 5)==0)
{ {
AddPinholeArgs[0].elt = "RemoteHost"; AddPinholeArgs[0].elt = "RemoteHost";
@ -912,7 +912,7 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype,
resVal = GetValueFromNameValueList(&pdata, "errorCode"); resVal = GetValueFromNameValueList(&pdata, "errorCode");
if(resVal) if(resVal)
{ {
//printf("AddPortMapping errorCode = '%s'\n", resVal); /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
ret = UPNPCOMMAND_UNKNOWN_ERROR; ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(resVal, "%d", &ret); 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 /* Project : miniupnp
* Author : Thomas BERNARD * Author : Thomas BERNARD
* copyright (c) 2007 Thomas Bernard * copyright (c) 2007 Thomas Bernard
@ -97,7 +97,7 @@ const char * strupnperror(int err)
s = "ExternalPortOnlySupportsWildcard"; s = "ExternalPortOnlySupportsWildcard";
break; break;
default: default:
s = NULL; s = "UnknownError";
break; break;
} }
return s; 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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * 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 * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -90,7 +90,7 @@ ClearNameValueList(struct NameValueParserData * pdata)
} }
} }
char * char *
GetValueFromNameValueList(struct NameValueParserData * pdata, GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name) const char * Name)
{ {
@ -131,7 +131,7 @@ GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
} }
#endif #endif
/* debug all-in-one function /* debug all-in-one function
* do parsing then display to stdout */ * do parsing then display to stdout */
#ifdef DEBUG #ifdef DEBUG
void void