update miniupnpc

This commit is contained in:
Riccardo Spagni 2016-03-21 13:37:54 +02:00
parent bdc07f029a
commit a4242c42b2
No known key found for this signature in database
GPG key ID: 55432DF31CCD4FCD
13 changed files with 174 additions and 68 deletions

View file

@ -1,6 +1,14 @@
$Id: Changelog.txt,v 1.219 2015/10/26 17:05:06 nanard Exp $ $Id: Changelog.txt,v 1.222 2016/01/24 17:24:35 nanard Exp $
miniUPnP client Changelog. miniUPnP client Changelog.
2016/01/24:
change miniwget to return HTTP status code
increments API_VERSION to 16
2016/01/22:
Improve UPNPIGD_IsConnected() to check if WAN address is not private.
parse HTTP response status line in miniwget.c
2015/10/26: 2015/10/26:
snprintf() overflow check. check overflow in simpleUPnPcommand2() snprintf() overflow check. check overflow in simpleUPnPcommand2()

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.126 2015/08/28 12:14:18 nanard Exp $ # $Id: Makefile,v 1.133 2016/01/24 17:24:35 nanard Exp $
# MiniUPnP Project # MiniUPnP Project
# http://miniupnp.free.fr/ # http://miniupnp.free.fr/
# http://miniupnp.tuxfamily.org/ # http://miniupnp.tuxfamily.org/
@ -66,7 +66,7 @@ ifeq (SunOS, $(OS))
endif endif
# APIVERSION is used to build SONAME # APIVERSION is used to build SONAME
APIVERSION = 15 APIVERSION = 16
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 \

View file

@ -18,7 +18,8 @@ OBJS=miniwget.o minixml.o igd_desc_parse.o minisoap.o \
upnpdev.o upnpdev.o
OBJSDLL=$(addprefix dll/, $(OBJS)) OBJSDLL=$(addprefix dll/, $(OBJS))
all: init upnpc-static upnpc-shared testminixml libminiupnpc.a miniupnpc.dll all: init upnpc-static upnpc-shared testminixml libminiupnpc.a \
miniupnpc.dll listdevices
init: init:
mkdir dll mkdir dll
@ -66,6 +67,9 @@ upnpc-static: upnpc.o libminiupnpc.a
upnpc-shared: dll/upnpc.o miniupnpc.lib upnpc-shared: dll/upnpc.o miniupnpc.lib
$(CC) -o $@ $^ $(LDLIBS) $(CC) -o $@ $^ $(LDLIBS)
listdevices: listdevices.o libminiupnpc.a
$(CC) -o $@ $^ $(LDLIBS)
wingenminiupnpcstrings: wingenminiupnpcstrings.o wingenminiupnpcstrings: wingenminiupnpcstrings.o
wingenminiupnpcstrings.o: wingenminiupnpcstrings.c wingenminiupnpcstrings.o: wingenminiupnpcstrings.c

View file

@ -1,7 +1,12 @@
$Id: apiversions.txt,v 1.7 2015/07/23 20:40:08 nanard Exp $ $Id: apiversions.txt,v 1.9 2016/01/24 17:24:36 nanard Exp $
Differences in API between miniUPnPc versions Differences in API between miniUPnPc versions
API version 16
added "status_code" argument to getHTTPResponse(), miniwget() and miniwget_getaddr()
updated macro :
#define MINIUPNPC_API_VERSION 16
API version 15 API version 15
changed "sameport" argument of upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() changed "sameport" argument of upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice()
to "localport". When 0 or 1, behaviour is not changed, but it can take to "localport". When 0 or 1, behaviour is not changed, but it can take

View file

@ -1,5 +1,6 @@
/* $Id: minissdpc.c,v 1.28 2015/09/18 13:05:39 nanard Exp $ */ /* $Id: minissdpc.c,v 1.28 2015/09/18 13:05:39 nanard Exp $ */
/* Project : miniupnp /* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp
* Web : http://miniupnp.free.fr/ * Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD * Author : Thomas BERNARD
* copyright (c) 2005-2015 Thomas Bernard * copyright (c) 2005-2015 Thomas Bernard
@ -67,6 +68,10 @@ struct sockaddr_un {
#define HAS_IP_MREQN #define HAS_IP_MREQN
#endif #endif
#if !defined(HAS_IP_MREQN) && !defined(_WIN32)
#include <sys/ioctl.h>
#endif
#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) #if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN)
/* Several versions of glibc don't define this structure, /* Several versions of glibc don't define this structure,
* define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */ * define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */
@ -647,11 +652,25 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
{ {
PRINT_SOCKET_ERROR("setsockopt"); PRINT_SOCKET_ERROR("setsockopt");
} }
#else #elif !defined(_WIN32)
struct ifreq ifr;
int ifrlen = sizeof(ifr);
strncpy(ifr.ifr_name, multicastif, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0)
{
PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)");
}
mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt");
}
#else /* _WIN32 */
#ifdef DEBUG #ifdef DEBUG
printf("Setting of multicast interface not supported with interface name.\n"); printf("Setting of multicast interface not supported with interface name.\n");
#endif #endif
#endif #endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */
} }
} }
} }

View file

@ -1,9 +1,9 @@
/* $Id: miniupnpc.c,v 1.135 2015/07/23 20:40:08 nanard Exp $ */ /* $Id: miniupnpc.c,v 1.148 2016/01/24 17:24:36 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab */ /* vim: tabstop=4 shiftwidth=4 noexpandtab
/* Project : miniupnp * Project : miniupnp
* Web : http://miniupnp.free.fr/ * Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD * Author : Thomas BERNARD
* copyright (c) 2005-2015 Thomas Bernard * copyright (c) 2005-2016 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. */
#include <stdlib.h> #include <stdlib.h>
@ -72,6 +72,25 @@
#define SERVICEPREFIX "u" #define SERVICEPREFIX "u"
#define SERVICEPREFIX2 'u' #define SERVICEPREFIX2 'u'
/* check if an ip address is a private (LAN) address
* see https://tools.ietf.org/html/rfc1918 */
static int is_rfc1918addr(const char * addr)
{
/* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */
if(COMPARE(addr, "192.168."))
return 1;
/* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */
if(COMPARE(addr, "10."))
return 1;
/* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */
if(COMPARE(addr, "172.")) {
int i = atoi(addr + 4);
if((16 <= i) && (i <= 31))
return 1;
}
return 0;
}
/* root description parsing */ /* root description parsing */
MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
{ {
@ -107,6 +126,7 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service,
int soapbodylen; int soapbodylen;
char * buf; char * buf;
int n; int n;
int status_code;
*bufsize = 0; *bufsize = 0;
snprintf(soapact, sizeof(soapact), "%s#%s", service, action); snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
@ -210,11 +230,15 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service,
return NULL; return NULL;
} }
buf = getHTTPResponse(s, bufsize); buf = getHTTPResponse(s, bufsize, &status_code);
#ifdef DEBUG #ifdef DEBUG
if(*bufsize > 0 && buf) if(*bufsize > 0 && buf)
{ {
printf("SOAP Response :\n%.*s\n", *bufsize, buf); printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf);
}
else
{
printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize);
} }
#endif #endif
closesocket(s); closesocket(s);
@ -526,7 +550,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
* 3 = an UPnP device has been found but was not recognized as an IGD * 3 = an UPnP device has been found but was not recognized as an IGD
* *
* In any positive non zero return case, the urls and data structures * In any positive non zero return case, the urls and data structures
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to * passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to
* free allocated memory. * free allocated memory.
*/ */
MINIUPNP_LIBSPEC int MINIUPNP_LIBSPEC int
@ -547,6 +571,8 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
int n_igd = 0; int n_igd = 0;
char extIpAddr[16]; char extIpAddr[16];
char myLanAddr[40]; char myLanAddr[40];
int status_code = -1;
if(!devlist) if(!devlist)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -570,7 +596,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
myLanAddr, sizeof(myLanAddr), myLanAddr, sizeof(myLanAddr),
dev->scope_id); dev->scope_id, &status_code);
#ifdef DEBUG #ifdef DEBUG
if(!desc[i].xml) if(!desc[i].xml)
{ {
@ -604,20 +630,25 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
parserootdesc(desc[i].xml, desc[i].size, data); parserootdesc(desc[i].xml, desc[i].size, data);
if(desc[i].is_igd || state >= 3 ) if(desc[i].is_igd || state >= 3 )
{ {
int is_connected;
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
/* in state 2 and 3 we dont test if device is connected ! */ /* in state 2 and 3 we dont test if device is connected ! */
if(state >= 2) if(state >= 2)
goto free_and_return; goto free_and_return;
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG #ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n", printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, urls->controlURL, is_connected);
UPNPIGD_IsConnected(urls, data));
#endif #endif
/* checks that status is connected AND there is a external IP address assigned */ /* checks that status is connected AND there is a external IP address assigned */
if(UPNPIGD_IsConnected(urls, data) if(is_connected &&
&& (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
goto free_and_return; if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
&& (0 != strcmp(extIpAddr, "0.0.0.0")))
goto free_and_return;
}
FreeUPNPUrls(urls); FreeUPNPUrls(urls);
if(data->second.servicetype[0] != '\0') { if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG #ifdef DEBUG
@ -629,14 +660,17 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
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, dev->scope_id); GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG #ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n", printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, urls->controlURL, is_connected);
UPNPIGD_IsConnected(urls, data));
#endif #endif
if(UPNPIGD_IsConnected(urls, data) if(is_connected &&
&& (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
goto free_and_return; if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
&& (0 != strcmp(extIpAddr, "0.0.0.0")))
goto free_and_return;
}
FreeUPNPUrls(urls); FreeUPNPUrls(urls);
} }
} }
@ -670,8 +704,9 @@ 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, 0); lanaddr, lanaddrlen, 0, NULL);
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));

View file

@ -1,8 +1,8 @@
/* $Id: miniupnpc.h,v 1.44 2015/07/23 20:40:10 nanard Exp $ */ /* $Id: miniupnpc.h,v 1.49 2016/01/24 17:24:36 nanard Exp $ */
/* Project: miniupnp /* Project: miniupnp
* http://miniupnp.free.fr/ * http://miniupnp.free.fr/
* Author: Thomas Bernard * Author: Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard * Copyright (c) 2005-2016 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_INCLUDED #ifndef MINIUPNPC_H_INCLUDED
@ -20,7 +20,7 @@
/* versions : */ /* versions : */
#define MINIUPNPC_VERSION "1.9" #define MINIUPNPC_VERSION "1.9"
#define MINIUPNPC_API_VERSION 15 #define MINIUPNPC_API_VERSION 16
/* Source port: /* Source port:
Using "1" as an alias for 1900 for backwards compatability Using "1" as an alias for 1900 for backwards compatability

View file

@ -1,8 +1,8 @@
/* $Id: miniwget.c,v 1.70 2015/07/15 12:41:13 nanard Exp $ */ /* $Id: miniwget.c,v 1.75 2016/01/24 17:24:36 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Website : http://miniupnp.free.fr/ * Website : http://miniupnp.free.fr/
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard * Copyright (c) 2005-2016 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. */
@ -65,7 +65,7 @@
* to the length parameter. * to the length parameter.
*/ */
void * void *
getHTTPResponse(int s, int * size) getHTTPResponse(int s, int * size, int * status_code)
{ {
char buf[2048]; char buf[2048];
int n; int n;
@ -83,7 +83,10 @@ getHTTPResponse(int s, int * size)
unsigned int content_buf_used = 0; unsigned int content_buf_used = 0;
char chunksize_buf[32]; char chunksize_buf[32];
unsigned int chunksize_buf_index; unsigned int chunksize_buf_index;
char * reason_phrase = NULL;
int reason_phrase_len = 0;
if(status_code) *status_code = -1;
header_buf = malloc(header_buf_len); header_buf = malloc(header_buf_len);
if(header_buf == NULL) if(header_buf == NULL)
{ {
@ -155,7 +158,7 @@ getHTTPResponse(int s, int * size)
continue; continue;
/* parse header lines */ /* parse header lines */
for(i = 0; i < endofheaders - 1; i++) { for(i = 0; i < endofheaders - 1; i++) {
if(colon <= linestart && header_buf[i]==':') if(linestart > 0 && colon <= linestart && header_buf[i]==':')
{ {
colon = i; colon = i;
while(i < (endofheaders-1) while(i < (endofheaders-1)
@ -166,7 +169,29 @@ getHTTPResponse(int s, int * size)
/* detecting end of line */ /* detecting end of line */
else if(header_buf[i]=='\r' || header_buf[i]=='\n') else if(header_buf[i]=='\r' || header_buf[i]=='\n')
{ {
if(colon > linestart && valuestart > colon) if(linestart == 0 && status_code)
{
/* Status line
* HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
int sp;
for(sp = 0; sp < i; sp++)
if(header_buf[sp] == ' ')
{
if(*status_code < 0)
*status_code = atoi(header_buf + sp + 1);
else
{
reason_phrase = header_buf + sp + 1;
reason_phrase_len = i - sp - 1;
break;
}
}
#ifdef DEBUG
printf("HTTP status code = %d, Reason phrase = %.*s\n",
*status_code, reason_phrase_len, reason_phrase);
#endif
}
else if(colon > linestart && valuestart > colon)
{ {
#ifdef DEBUG #ifdef DEBUG
printf("header='%.*s', value='%.*s'\n", printf("header='%.*s', value='%.*s'\n",
@ -337,7 +362,8 @@ static void *
miniwget3(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, unsigned int scope_id) const char * httpversion, unsigned int scope_id,
int * status_code)
{ {
char buf[2048]; char buf[2048];
int s; int s;
@ -435,7 +461,7 @@ miniwget3(const char * host,
sent += n; sent += n;
} }
} }
content = getHTTPResponse(s, size); content = getHTTPResponse(s, size, status_code);
closesocket(s); closesocket(s);
return content; return content;
} }
@ -444,18 +470,20 @@ miniwget3(const char * host,
* 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 * 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) unsigned int scope_id, int * status_code)
{ {
char * respbuffer; char * respbuffer;
#if 1 #if 1
respbuffer = miniwget3(host, port, path, size, respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1", scope_id); addr_str, addr_str_len, "1.1",
scope_id, status_code);
#else #else
respbuffer = miniwget3(host, port, path, size, respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.0", scope_id); addr_str, addr_str_len, "1.0",
scope_id, status_code);
if (*size == 0) if (*size == 0)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -463,7 +491,8 @@ miniwget2(const char * host,
#endif #endif
free(respbuffer); free(respbuffer);
respbuffer = miniwget3(host, port, path, size, respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1", scope_id); addr_str, addr_str_len, "1.1",
scope_id, status_code);
} }
#endif #endif
return respbuffer; return respbuffer;
@ -588,7 +617,8 @@ parseURL(const char * url,
} }
void * void *
miniwget(const char * url, int * size, unsigned int scope_id) miniwget(const char * url, int * size,
unsigned int scope_id, int * status_code)
{ {
unsigned short port; unsigned short port;
char * path; char * path;
@ -601,12 +631,13 @@ miniwget(const char * url, int * size, unsigned int scope_id)
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id); hostname, port, path, scope_id);
#endif #endif
return miniwget2(hostname, port, path, size, 0, 0, scope_id); return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code);
} }
void * void *
miniwget_getaddr(const char * url, int * size, miniwget_getaddr(const char * url, int * size,
char * addr, int addrlen, unsigned int scope_id) char * addr, int addrlen, unsigned int scope_id,
int * status_code)
{ {
unsigned short port; unsigned short port;
char * path; char * path;
@ -621,6 +652,6 @@ miniwget_getaddr(const char * url, int * size,
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id); hostname, port, path, scope_id);
#endif #endif
return miniwget2(hostname, port, path, size, addr, addrlen, scope_id); return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code);
} }

View file

@ -1,7 +1,7 @@
/* $Id: miniwget.h,v 1.7 2012/06/23 22:35:59 nanard Exp $ */ /* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard * Copyright (c) 2005-2016 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.
* */ * */
@ -14,11 +14,11 @@
extern "C" { extern "C" {
#endif #endif
MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size); MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code);
MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int); MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *);
MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int); MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *);
int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);

View file

@ -1,7 +1,7 @@
/* $Id: testminiwget.c,v 1.4 2012/06/23 22:35:59 nanard Exp $ */ /* $Id: testminiwget.c,v 1.5 2016/01/24 17:24:36 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2012 Thomas Bernard * Copyright (c) 2005-2016 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.
* */ * */
@ -20,15 +20,17 @@ int main(int argc, char * * argv)
int size, writtensize; int size, writtensize;
FILE *f; FILE *f;
char addr[64]; char addr[64];
int status_code = -1;
if(argc < 3) { if(argc < 3) {
fprintf(stderr, "Usage:\t%s url file\n", argv[0]); fprintf(stderr, "Usage:\t%s url file\n", argv[0]);
fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]); fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]);
return 1; return 1;
} }
data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr), 0); data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr), 0, &status_code);
if(!data) { if(!data || (status_code != 200)) {
fprintf(stderr, "Error fetching %s\n", argv[1]); if(data) free(data);
fprintf(stderr, "Error %d fetching %s\n", status_code, argv[1]);
return 1; return 1;
} }
printf("local address : %s\n", addr); printf("local address : %s\n", addr);

View file

@ -1,7 +1,7 @@
/* $Id: upnpc.c,v 1.111 2015/07/23 20:40:10 nanard Exp $ */ /* $Id: upnpc.c,v 1.114 2016/01/22 15:04:23 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard * Copyright (c) 2005-2016 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. */
@ -66,7 +66,7 @@ static void DisplayInfos(struct UPNPUrls * urls,
char connectionType[64]; char connectionType[64];
char status[64]; char status[64];
char lastconnerr[64]; char lastconnerr[64];
unsigned int uptime; unsigned int uptime = 0;
unsigned int brUp, brDown; unsigned int brUp, brDown;
time_t timenow, timestarted; time_t timenow, timestarted;
int r; int r;
@ -82,9 +82,11 @@ static void DisplayInfos(struct UPNPUrls * urls,
else else
printf("Status : %s, uptime=%us, LastConnectionError : %s\n", printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
status, uptime, lastconnerr); status, uptime, lastconnerr);
timenow = time(NULL); if(uptime > 0) {
timestarted = timenow - uptime; timenow = time(NULL);
printf(" Time started : %s", ctime(&timestarted)); timestarted = timenow - uptime;
printf(" Time started : %s", ctime(&timestarted));
}
if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
&brDown, &brUp) != UPNPCOMMAND_SUCCESS) { &brDown, &brUp) != UPNPCOMMAND_SUCCESS) {
printf("GetLinkLayerMaxBitRates failed.\n"); printf("GetLinkLayerMaxBitRates failed.\n");
@ -538,7 +540,7 @@ int main(int argc, char ** argv)
char ** commandargv = 0; char ** commandargv = 0;
int commandargc = 0; int commandargc = 0;
struct UPNPDev * devlist = 0; struct UPNPDev * devlist = 0;
char lanaddr[64]; /* my ip address on the LAN */ char lanaddr[64] = "unset"; /* my ip address on the LAN */
int i; int i;
const char * rootdescurl = 0; const char * rootdescurl = 0;
const char * multicastif = 0; const char * multicastif = 0;
@ -560,7 +562,7 @@ int main(int argc, char ** argv)
} }
#endif #endif
printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING);
printf(" (c) 2005-2015 Thomas Bernard.\n"); printf(" (c) 2005-2016 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 */

View file

@ -616,14 +616,14 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
protocol[3] = '\0'; protocol[3] = '\0';
} }
p = GetValueFromNameValueList(&pdata, "NewInternalClient"); p = GetValueFromNameValueList(&pdata, "NewInternalClient");
if(p && intClient) if(p)
{ {
strncpy(intClient, p, 16); strncpy(intClient, p, 16);
intClient[15] = '\0'; intClient[15] = '\0';
r = 0; r = 0;
} }
p = GetValueFromNameValueList(&pdata, "NewInternalPort"); p = GetValueFromNameValueList(&pdata, "NewInternalPort");
if(p && intPort) if(p)
{ {
strncpy(intPort, p, 6); strncpy(intPort, p, 6);
intPort[5] = '\0'; intPort[5] = '\0';