update miniupnpc
This commit is contained in:
parent
bdc07f029a
commit
a4242c42b2
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(×tarted));
|
timestarted = timenow - uptime;
|
||||||
|
printf(" Time started : %s", ctime(×tarted));
|
||||||
|
}
|
||||||
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 */
|
||||||
|
|
|
@ -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';
|
||||||
|
|
Loading…
Reference in New Issue