Merge branch 'master' into randomize_url

This commit is contained in:
Thomas Bernard 2017-05-26 17:30:18 +02:00
commit 11fcf5a008
18 changed files with 456 additions and 198 deletions

2
README
View File

@ -11,7 +11,7 @@ miniupnpc/ : MiniUPnP client - an UPnP IGD control point
miniupnpd/ : MiniUPnP daemon - an implementation of a UPnP IGD
+ NAT-PMP / PCP gateway
minissdpd/ : SSDP managing daemon. Designed to work with miniupnpc,
miniupnpd, minidlna, etc.
miniupnpd, ReadyMedia (formerly MiniDLNA), etc.
miniupnpc-async/ : Proof of concept for a UPnP IGD control point using
asynchronous (non blocking) sockets.
miniupnpc-libevent/ : UPnP IGD control point using libevent2

View File

@ -1,10 +1,10 @@
#!/bin/sh
# $Id: testminissdpd.sh,v 1.2 2015/09/03 18:31:25 nanard Exp $
# (c) 2016 Thomas Bernard
# $Id: testminissdpd.sh,v 1.8 2017/04/21 11:57:59 nanard Exp $
# (c) 2017 Thomas Bernard
OS=`uname -s`
IF=lo
if [ "$OS" = "Darwin" ] || [ "$OS" = "SunOS" ] ; then
if [ "$OS" = "Darwin" ] || [ "$OS" = "OpenBSD" ] || [ "$OS" = "SunOS" ] || [ "$OS" = "FreeBSD" ] ; then
IF=lo0
fi
# if set, 1st argument is network interface

View File

@ -5,7 +5,7 @@ Pod::Spec.new do |spec|
spec.authors = "The MiniUPnP Authors"
spec.license = { type: "BSD", file: "miniupnpc/LICENSE" }
spec.version = "2.0.0.0"
spec.version = "2.0.0.2"
spec.source = {
git: 'https://github.com/cpp-ethereum-ios/miniupnp.git',
tag: "v#{spec.version}"
@ -36,12 +36,13 @@ Pod::Spec.new do |spec|
CC=`xcrun -sdk $PLATFORM -find cc` \
CFLAGS="-arch $ARCH -isysroot $SDKPATH" \
LIBTOOL=`xcrun -sdk $PLATFORM -find libtool` \
LDFLAGS="-arch $ARCH"
LDFLAGS="-arch $ARCH -headerpad_max_install_names"
}
create_universal_library() {
lipo -create -output build-ios/libminiupnpc.dylib \
lipo -create -output libminiupnpc.dylib \
build-ios/{armv7,arm64,i386,x86_64}/usr/lib/libminiupnpc.dylib
install_name_tool -id "@rpath/libminiupnpc.dylib" libminiupnpc.dylib
}
cd miniupnpc
@ -49,5 +50,5 @@ Pod::Spec.new do |spec|
CMD
spec.source_files = "miniupnpc/build-ios/armv7/usr/include/**/*.h"
spec.ios.vendored_libraries = "miniupnpc/build-ios/libminiupnpc.dylib"
spec.ios.vendored_libraries = "miniupnpc/libminiupnpc.dylib"
end

View File

@ -1,13 +1,15 @@
# $Id: Makefile,v 1.9 2014/11/04 22:25:00 nanard Exp $
# $Id: Makefile,v 1.12 2017/05/26 11:01:37 nanard Exp $
# MiniUPnP Project
# http://miniupnp.free.fr/
# (c) 2005-2014 Thomas Bernard
# (c) 2005-2017 Thomas Bernard
# to install use :
# $ PREFIX=/tmp/dummylocation make install
# or
# $ INSTALLPREFIX=/usr/local make install
# or
# make install (will go to /usr/bin, /usr/lib, etc...)
OS = $(shell uname -s)
CC ?= gcc
#AR = gar
CFLAGS = -O0 -g -DDEBUG
@ -16,10 +18,15 @@ CFLAGS += -fPIC
CFLAGS += -ansi
CFLAGS += -Wall -W
CFLAGS += -D_BSD_SOURCE
ifneq ($(OS), FreeBSD)
ifneq ($(OS), Darwin)
#CFLAGS += -D_POSIX_C_SOURCE=200112L
CFLAGS += -D_XOPEN_SOURCE=600
endif
endif
CFLAGS += -DUPNPC_USE_SELECT
INSTALL = install
OS = $(shell uname -s)
#following libs are needed on Solaris
ifeq ($(OS), SunOS)
LDLIBS += -lsocket -lnsl -lresolv

View File

@ -1,6 +1,6 @@
/* $Id: miniupnpc-async.c,v 1.19 2014/11/07 12:05:40 nanard Exp $ */
/* miniupnpc-async
* Copyright (c) 2008-2014, Thomas BERNARD <miniupnp@free.fr>
* Copyright (c) 2008-2017, Thomas BERNARD <miniupnp@free.fr>
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -72,8 +72,8 @@ struct upnp_args {
/* private functions */
static int upnpc_connect(upnpc_t * p, const char * url);
static int upnpc_send_request(upnpc_t * p);
static int upnpc_connect(upnpc_device_t * p, const char * url);
static int upnpc_send_request(upnpc_device_t * p);
/* parse_msearch_reply()
@ -83,8 +83,8 @@ static int upnpc_send_request(upnpc_t * p);
* The strings are NOT null terminated */
static void
parse_msearch_reply(const char * reply, int size,
const char * * location, int * locationsize,
const char * * st, int * stsize)
const char * * location, unsigned int * locationsize,
const char * * st, unsigned int * stsize)
{
int a, b, i;
i = 0; /* current character index */
@ -147,26 +147,26 @@ static int upnpc_send_ssdp_msearch(upnpc_t * p, const char * device, unsigned in
int err = SOCKET_ERROR;
if(err == EINTR || WOULDBLOCK(err)) {
debug_printf("upnpc_send_ssdp_msearch: should try again");
p->state = ESendSSDP;
p->state = EUPnPSendSSDP;
return 0;
}
PRINT_SOCKET_ERROR("sendto");
return -1;
}
p->state = EReceiveSSDP;
p->state = EUPnPReceiveSSDP;
return 0;
}
static int upnpc_set_root_desc_location(upnpc_t * p, const char * location, int locationsize)
static int upnpc_set_root_desc_location(upnpc_device_t * d, const char * location, int locationsize)
{
char * tmp;
tmp = realloc(p->root_desc_location, locationsize + 1);
tmp = realloc(d->root_desc_location, locationsize + 1);
if(tmp == 0) {
return -1;
}
memcpy(tmp, location, locationsize);
tmp[locationsize] = '\0';
p->root_desc_location = tmp;
d->root_desc_location = tmp;
return 0;
}
@ -181,23 +181,41 @@ static int upnpc_receive_and_parse_ssdp(upnpc_t * p)
debug_printf("empty packet received\n");
} else {
const char * location = NULL;
int locationsize;
unsigned int locationsize;
const char * st = NULL;
int stsize;
unsigned int stsize;
debug_printf("%.*s", n, bufr);
parse_msearch_reply(bufr, n, &location, &locationsize, &st, &stsize);
debug_printf("location = '%.*s'\n", locationsize, location);
debug_printf("st = '%.*s'\n", stsize, st);
if(location != NULL) {
if(upnpc_set_root_desc_location(p, location, locationsize) < 0) {
p->state = EError;
upnpc_device_t * dev = p->device_list;
while(dev != NULL) {
if(dev->root_desc_location != NULL
&& strlen(dev->root_desc_location) == locationsize
&& memcmp(dev->root_desc_location, location, locationsize) == 0) {
debug_printf("device already in list (location='%s')\n", dev->root_desc_location);
return -1;
}
p->state = EGetDescConnect;
upnpc_connect(p, p->root_desc_location);
dev = dev->next;
}
dev = calloc(1, sizeof(upnpc_device_t));
if(dev == NULL) {
p->state = EUPnPError;
return -1;
}
if(upnpc_set_root_desc_location(dev, location, locationsize) < 0) {
free(dev);
p->state = EUPnPError;
return -1;
}
dev->next = p->device_list;
p->device_list = dev;
dev->state = EDevGetDescConnect;
upnpc_connect(dev, dev->root_desc_location);
} else {
/* or do nothing ? */
p->state = EError;
p->state = EUPnPError;
}
}
return 0;
@ -298,7 +316,7 @@ parseURL(const char * url,
return 1;
}
static int upnpc_connect(upnpc_t * p, const char * url)
static int upnpc_connect(upnpc_device_t * p, const char * url)
{
int r;
char hostname[MAXHOSTNAMELEN+1];
@ -308,19 +326,19 @@ static int upnpc_connect(upnpc_t * p, const char * url)
struct sockaddr_in addr;
socklen_t addrlen;
if(p->root_desc_location == 0) {
/*if(p->root_desc_location == 0) {
p->state = EError;
return -1;
}
}*/
if(!parseURL(url/*p->root_desc_location*/, hostname, &port,
&path, &scope_id)) {
p->state = EError;
p->state = EDevError;
return -1;
}
p->http_socket = socket(PF_INET, SOCK_STREAM, 0);
if(p->http_socket < 0) {
PRINT_SOCKET_ERROR("socket");
p->state = EError;
p->state = EDevError;
return -1;
}
if(!set_non_blocking(p->http_socket)) {
@ -339,44 +357,44 @@ static int upnpc_connect(upnpc_t * p, const char * url)
return 0;
} else if(errno != EINTR) {
PRINT_SOCKET_ERROR("connect");
p->state = EError;
p->state = EDevError;
return -1;
}
}
} while(r < 0 && errno == EINTR);
if(p->state == EGetDescConnect) {
p->state = EGetDescRequest;
if(p->state == EDevGetDescConnect) {
p->state = EDevGetDescRequest;
} else {
p->state = ESoapRequest;
p->state = EDevSoapRequest;
}
upnpc_send_request(p);
return 0;
}
static int upnpc_complete_connect(upnpc_t * p)
static int upnpc_complete_connect(upnpc_device_t * p)
{
socklen_t len;
int err;
len = sizeof(err);
if(getsockopt(p->http_socket, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
PRINT_SOCKET_ERROR("getsockopt");
p->state = EError;
p->state = EDevError;
return -1;
}
if(err != 0) {
debug_printf("connect failed %d\n", err);
p->state = EError;
p->state = EDevError;
return -1;
}
if(p->state == EGetDescConnect)
p->state = EGetDescRequest;
if(p->state == EDevGetDescConnect)
p->state = EDevGetDescRequest;
else
p->state = ESoapRequest;
p->state = EDevSoapRequest;
upnpc_send_request(p);
return 0;
}
static int upnpc_send_request(upnpc_t * p)
static int upnpc_send_request(upnpc_device_t * p)
{
ssize_t n;
static const char reqfmt[] = "GET %s HTTP/1.1\r\n"
@ -384,6 +402,13 @@ static int upnpc_send_request(upnpc_t * p)
"Connection: Close\r\n"
"User-Agent: MiniUPnPc-async\r\n"
"\r\n";
/* retrieve "our" IP address used to connect to the UPnP device */
p->selfaddrlen = sizeof(struct sockaddr_storage);
if(getsockname(p->http_socket, (struct sockaddr *)&p->selfaddr, &p->selfaddrlen) < 0) {
PRINT_SOCKET_ERROR("getsockname()");
}
if(p->http_request == NULL) {
char hostname[MAXHOSTNAMELEN+1];
unsigned short port;
@ -392,13 +417,13 @@ static int upnpc_send_request(upnpc_t * p)
int len;
if(!parseURL(p->root_desc_location, hostname, &port,
&path, &scope_id)) {
p->state = EError;
p->state = EDevError;
return -1;
}
len = snprintf(NULL, 0, reqfmt, path, hostname, port);
p->http_request = malloc(len + 1);
if(p->http_request == NULL) {
p->state = EError;
p->state = EDevError;
return -1;
}
p->http_request_len = snprintf(p->http_request, len + 1,
@ -409,7 +434,7 @@ static int upnpc_send_request(upnpc_t * p)
p->http_request_len - p->http_request_sent, 0/* flags */);
if(n < 0) {
PRINT_SOCKET_ERROR("send");
p->state = EError;
p->state = EDevError;
return -1;
} else {
debug_printf("sent %d bytes\n", (int)n);
@ -426,10 +451,10 @@ static int upnpc_send_request(upnpc_t * p)
free(p->http_request);
p->http_request = NULL;
p->http_request_len = 0;
if(p->state == EGetDescRequest)
p->state = EGetDescResponse;
if(p->state == EDevGetDescRequest)
p->state = EDevGetDescResponse;
else
p->state = ESoapResponse;
p->state = EDevSoapResponse;
free(p->http_response);
p->http_response = NULL;
p->http_response_received = 0;
@ -440,7 +465,7 @@ static int upnpc_send_request(upnpc_t * p)
return 0;
}
static int upnpc_parse_headers(upnpc_t * p)
static int upnpc_parse_headers(upnpc_device_t * p)
{
/* search for CR LF CR LF (end of headers)
* recognize also LF LF */
@ -547,7 +572,7 @@ static char * build_url_string(const char * urlbase, const char * root_desc_url,
return s;
}
static int upnpc_get_response(upnpc_t * p)
static int upnpc_get_response(upnpc_device_t * p)
{
ssize_t n;
ssize_t count;
@ -566,7 +591,7 @@ static int upnpc_get_response(upnpc_t * p)
if(errno == EINTR || WOULDBLOCK(errno))
return 0; /* try again later */
PRINT_SOCKET_ERROR("read");
p->state = EError;
p->state = EDevError;
return -1;
} else if(n == 0) {
/* receiving finished */
@ -579,7 +604,7 @@ static int upnpc_get_response(upnpc_t * p)
}
/* TODO : decode chunked transfer-encoding */
/* parse xml */
if(p->state == EGetDescResponse) {
if(p->state == EDevGetDescResponse) {
struct IGDdatas igd;
struct xmlparser parser;
memset(&igd, 0, sizeof(struct IGDdatas));
@ -608,7 +633,7 @@ static int upnpc_get_response(upnpc_t * p)
p->http_response = NULL;
p->http_response_received = 0;
p->http_response_end_of_headers = 0;
p->state = EReady;
p->state = EDevReady;
} else {
/* receiving in progress */
debug_printf("received %d bytes:\n%.*s\n", (int)n, (int)n, buffer);
@ -616,7 +641,7 @@ static int upnpc_get_response(upnpc_t * p)
p->http_response = malloc(n);
if(p->http_response == NULL) {
debug_printf("failed to malloc %d bytes\n", (int)n);
p->state = EError;
p->state = EDevError;
return -1;
}
p->http_response_received = n;
@ -625,7 +650,7 @@ static int upnpc_get_response(upnpc_t * p)
char * tmp = realloc(p->http_response, p->http_response_received + n);
if(tmp == NULL) {
debug_printf("failed to realloc %d bytes\n", (int)(p->http_response_received + n));
p->state = EError;
p->state = EDevError;
return -1;
}
p->http_response = tmp;
@ -643,7 +668,7 @@ static int upnpc_get_response(upnpc_t * p)
#define SERVICEPREFIX "u"
#define SERVICEPREFIX2 'u'
static int upnpc_build_soap_request(upnpc_t * p, const char * url,
static int upnpc_build_soap_request(upnpc_device_t * p, const char * url,
const char * service,
const char * action,
const struct upnp_args * args, int arg_count)
@ -689,7 +714,7 @@ static int upnpc_build_soap_request(upnpc_t * p, const char * url,
}
args_xml = malloc(++l);
if(args_xml == NULL) {
p->state = EError;
p->state = EDevError;
return -1;
}
for(i = 0, n = 0; i < arg_count && n < l; i++) {
@ -702,7 +727,7 @@ static int upnpc_build_soap_request(upnpc_t * p, const char * url,
body_len = snprintf(NULL, 0, fmt_soap, action, service, args_xml?args_xml:"", action);
body = malloc(body_len + 1);
if(body == NULL) {
p->state = EError;
p->state = EDevError;
free(args_xml);
return -1;
}
@ -712,7 +737,7 @@ static int upnpc_build_soap_request(upnpc_t * p, const char * url,
free(args_xml);
args_xml = NULL;
if(!parseURL(url, hostname, &port, &path, &scope_id)) {
p->state = EError;
p->state = EDevError;
free(body);
return -1;
}
@ -741,7 +766,7 @@ int upnpc_init(upnpc_t * p, const char * multicastif)
struct sockaddr_in addr;
if(!p)
return UPNPC_ERR_INVALID_ARGS;
p->state = EError;
p->state = EUPnPError;
memset(p, 0, sizeof(upnpc_t)); /* clean everything */
/* open the socket for SSDP */
p->ssdp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
@ -782,57 +807,62 @@ int upnpc_init(upnpc_t * p, const char * multicastif)
return UPNPC_ERR_BIND_FAILED;
}
p->state = EInit;
p->state = EUPnPInit;
return UPNPC_OK;
}
int upnpc_finalize(upnpc_t * p)
{
if(!p) return UPNPC_ERR_INVALID_ARGS;
free(p->root_desc_location);
p->root_desc_location = NULL;
free(p->http_request);
p->http_request = NULL;
free(p->http_response);
p->http_response = NULL;
free(p->control_cif_url);
p->control_cif_url = NULL;
free(p->control_conn_url);
p->control_conn_url = NULL;
if(p->ssdp_socket >= 0) {
close(p->ssdp_socket);
p->ssdp_socket = -1;
}
if(p->http_socket >= 0) {
close(p->http_socket);
p->http_socket = -1;
while(p->device_list) {
upnpc_device_t * next = p->device_list->next;
free(p->device_list->root_desc_location);
p->device_list->root_desc_location = NULL;
free(p->device_list->http_request);
p->device_list->http_request = NULL;
free(p->device_list->http_response);
p->device_list->http_response = NULL;
free(p->device_list->control_cif_url);
p->device_list->control_cif_url = NULL;
free(p->device_list->control_conn_url);
p->device_list->control_conn_url = NULL;
if(p->device_list->http_socket >= 0) {
close(p->device_list->http_socket);
p->device_list->http_socket = -1;
}
ClearNameValueList(&p->soap_response_data);
p->state = EFinalized;
ClearNameValueList(&p->device_list->soap_response_data);
free(p->device_list);
p->device_list = next;
}
p->state = EUPnPFinalized;
return UPNPC_OK;
}
int upnpc_get_external_ip_address(upnpc_t * p)
int upnpc_get_external_ip_address(upnpc_device_t * p)
{
upnpc_build_soap_request(p, p->control_conn_url,
"urn:schemas-upnp-org:service:WANIPConnection:1",
"GetExternalIPAddress", NULL, 0);
p->state = ESoapConnect;
p->state = EDevSoapConnect;
upnpc_connect(p, p->control_conn_url);
return 0;
}
int upnpc_get_link_layer_max_rate(upnpc_t * p)
int upnpc_get_link_layer_max_rate(upnpc_device_t * p)
{
upnpc_build_soap_request(p, p->control_cif_url,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
"GetCommonLinkProperties", NULL, 0);
p->state = ESoapConnect;
p->state = EDevSoapConnect;
upnpc_connect(p, p->control_conn_url);
return 0;
}
int upnpc_add_port_mapping(upnpc_t * p,
int upnpc_add_port_mapping(upnpc_device_t * p,
const char * remote_host, unsigned short ext_port,
unsigned short int_port, const char * int_client,
const char * proto, const char * description,
@ -868,7 +898,7 @@ int upnpc_add_port_mapping(upnpc_t * p,
"urn:schemas-upnp-org:service:WANIPConnection:1",
"AddPortMapping",
args, 8);
p->state = ESoapConnect;
p->state = EDevSoapConnect;
upnpc_connect(p, p->control_conn_url);
return 0;
}
@ -876,42 +906,69 @@ int upnpc_add_port_mapping(upnpc_t * p,
#ifdef UPNPC_USE_SELECT
int upnpc_select_fds(upnpc_t * p, int * nfds, fd_set * readfds, fd_set * writefds)
{
upnpc_device_t * d;
int n = 0;
if(!p) return UPNPC_ERR_INVALID_ARGS;
for(d = p->device_list; d != NULL; d = d->next) {
switch(d->state) {
case EDevGetDescConnect:
case EDevGetDescRequest:
case EDevSoapConnect:
case EDevSoapRequest:
FD_SET(d->http_socket, writefds);
if(*nfds < d->http_socket)
*nfds = d->http_socket;
n++;
break;
case EDevGetDescResponse:
case EDevSoapResponse:
FD_SET(d->http_socket, readfds);
if(*nfds < d->http_socket)
*nfds = d->http_socket;
n++;
break;
default:
break;
}
}
switch(p->state) {
case ESendSSDP:
case EUPnPSendSSDP:
FD_SET(p->ssdp_socket, writefds);
if(*nfds < p->ssdp_socket)
*nfds = p->ssdp_socket;
n++;
break;
case EReceiveSSDP:
case EUPnPReceiveSSDP:
default:
/* still receive SSDP responses when processing Description, etc. */
FD_SET(p->ssdp_socket, readfds);
if(*nfds < p->ssdp_socket)
*nfds = p->ssdp_socket;
n++;
break;
case EGetDescConnect:
case EGetDescRequest:
case ESoapConnect:
case ESoapRequest:
FD_SET(p->http_socket, writefds);
if(*nfds < p->http_socket)
*nfds = p->http_socket;
n++;
break;
case EGetDescResponse:
case ESoapResponse:
FD_SET(p->http_socket, readfds);
if(*nfds < p->http_socket)
*nfds = p->http_socket;
n++;
break;
default:
return 0;
}
return n;
}
void upnpc_check_select_fds(upnpc_t * p, const fd_set * readfds, const fd_set * writefds)
{
upnpc_device_t * d;
p->socket_flags = 0;
if(FD_ISSET(p->ssdp_socket, readfds))
p->socket_flags = UPNPC_SSDP_READABLE;
if(FD_ISSET(p->ssdp_socket, writefds))
p->socket_flags = UPNPC_SSDP_WRITEABLE;
for(d = p->device_list; d != NULL; d = d->next) {
d->socket_flags = 0;
if(FD_ISSET(d->http_socket, readfds))
d->socket_flags = UPNPC_HTTP_READABLE;
if(FD_ISSET(d->http_socket, writefds))
d->socket_flags = UPNPC_HTTP_WRITEABLE;
}
}
#endif
static const char * devices_to_search[] = {
@ -924,6 +981,7 @@ static const char * devices_to_search[] = {
int upnpc_process(upnpc_t * p)
{
upnpc_device_t * d;
/*
1) Envoyer les paquets de discovery SSDP
2) Recevoir et traiter les reponses
@ -931,31 +989,51 @@ int upnpc_process(upnpc_t * p)
4) tester les etats
*/
if(!p) return UPNPC_ERR_INVALID_ARGS;
debug_printf("state=%d\n", (int)p->state);
switch(p->state) {
case EInit:
upnpc_send_ssdp_msearch(p, devices_to_search[0], 2);
debug_printf("state=%d socket_flags=0x%04x\n", (int)p->state, p->socket_flags);
for(d = p->device_list; d != NULL; d = d->next) {
switch(d->state) {
case EDevGetDescConnect:
case EDevSoapConnect:
upnpc_complete_connect(d);
break;
case ESendSSDP:
upnpc_send_ssdp_msearch(p, devices_to_search[0], 2);
case EDevGetDescRequest:
case EDevSoapRequest:
upnpc_send_request(d);
break;
case EReceiveSSDP:
case EDevGetDescResponse:
case EDevSoapResponse:
upnpc_get_response(d);
break;
default:
break;
}
}
/* all devices ready => ready */
if(p->device_list != NULL) {
d = p->device_list;
while(d && d->state == EDevReady) d = d->next;
p->state = (d == NULL) ? EUPnPReady : EUPnPProcessing;
}
if(p->socket_flags & UPNPC_SSDP_READABLE) {
upnpc_receive_and_parse_ssdp(p);
}
switch(p->state) {
case EUPnPInit:
upnpc_send_ssdp_msearch(p, devices_to_search[0], 2);
break;
case EUPnPSendSSDP:
upnpc_send_ssdp_msearch(p, devices_to_search[0], 2);
break;
case EUPnPReceiveSSDP:
/*upnpc_receive_and_parse_ssdp(p);*/
break;
/*case EGetDesc:
upnpc_connect(p);
break;*/
case EGetDescConnect:
case ESoapConnect:
upnpc_complete_connect(p);
break;
case EGetDescRequest:
case ESoapRequest:
upnpc_send_request(p);
break;
case EGetDescResponse:
case ESoapResponse:
upnpc_get_response(p);
case EUPnPReady:
case EUPnPProcessing:
break;
default:
return UPNPC_ERR_UNKNOWN_STATE;

View File

@ -1,6 +1,6 @@
/* $Id: miniupnpc-async.h,v 1.13 2014/11/07 11:25:52 nanard Exp $ */
/* miniupnpc-async
* Copyright (c) 2008-2014, Thomas BERNARD <miniupnp@free.fr>
* Copyright (c) 2008-2017, Thomas BERNARD <miniupnp@free.fr>
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -17,6 +17,9 @@
#ifndef MINIUPNPC_ASYNC_H_INCLUDED
#define MINIUPNPC_ASYNC_H_INCLUDED
/* for struct sockaddr_storage */
#include <netinet/in.h>
#include "declspec.h"
#include "upnpreplyparse.h"
@ -30,25 +33,30 @@ extern "C" {
#define UPNPC_ERR_BIND_FAILED (-3)
#define UPNPC_ERR_UNKNOWN_STATE (-4)
typedef struct {
#define UPNPC_SSDP_READABLE 0x0001
#define UPNPC_SSDP_WRITEABLE 0x0100
#define UPNPC_HTTP_READABLE 0x0002
#define UPNPC_HTTP_WRITEABLE 0x0200
typedef struct upnpc_device {
struct upnpc_device * next;
enum {
EInit = 1,
ESendSSDP,
EReceiveSSDP,
/*EGetDesc,*/
EGetDescConnect,
EGetDescRequest,
EGetDescResponse,
EReady,
ESoapConnect,
ESoapRequest,
ESoapResponse,
EFinalized = 99,
EError = 1000
EDevInit = 1,
EDevGetDescConnect,
EDevGetDescRequest,
EDevGetDescResponse,
EDevReady,
EDevSoapConnect,
EDevSoapRequest,
EDevSoapResponse,
EDevFinalized = 99,
EDevError = 1000
} state;
int ssdp_socket;
char * root_desc_location;
char * control_cif_url;
char * control_conn_url;
int http_socket;
int socket_flags; /* see UPNPC_*_READABLE, etc. */
char * http_request;
int http_request_len;
int http_request_sent;
@ -58,20 +66,36 @@ typedef struct {
int http_response_content_length;
int http_response_chunked;
int http_response_code;
char * control_cif_url;
char * control_conn_url;
struct NameValueParserData soap_response_data;
struct sockaddr_storage selfaddr;
socklen_t selfaddrlen;
} upnpc_device_t;
typedef struct {
enum {
EUPnPInit = 1,
EUPnPSendSSDP,
EUPnPReceiveSSDP,
EUPnPGetDesc,
EUPnPReady,
EUPnPProcessing,
EUPnPFinalized = 99,
EUPnPError = 1000
} state;
int socket_flags; /* see UPNPC_*_READABLE, etc. */
int ssdp_socket;
upnpc_device_t * device_list;
} upnpc_t;
int upnpc_init(upnpc_t * p, const char * multicastif);
int upnpc_finalize(upnpc_t * p);
int upnpc_get_external_ip_address(upnpc_t * p);
int upnpc_get_external_ip_address(upnpc_device_t * p);
int upnpc_get_link_layer_max_rate(upnpc_t * p);
int upnpc_get_link_layer_max_rate(upnpc_device_t * p);
int upnpc_add_port_mapping(upnpc_t * p,
int upnpc_add_port_mapping(upnpc_device_t * p,
const char * remote_host, unsigned short ext_port,
unsigned short int_port, const char * int_client,
const char * proto, const char * description,
@ -79,6 +103,7 @@ int upnpc_add_port_mapping(upnpc_t * p,
#ifdef UPNPC_USE_SELECT
int upnpc_select_fds(upnpc_t * p, int * nfds, fd_set * readfds, fd_set * writefds);
void upnpc_check_select_fds(upnpc_t * p, const fd_set * readfds, const fd_set * writefds);
#endif /* UPNPC_USE_SELECT */
int upnpc_process(upnpc_t * p);

View File

@ -1,6 +1,6 @@
/* $Id: testasync.c,v 1.14 2014/11/07 12:07:38 nanard Exp $ */
/* miniupnpc-async
* Copyright (c) 2008-2014, Thomas BERNARD <miniupnp@free.fr>
* Copyright (c) 2008-2017, Thomas BERNARD <miniupnp@free.fr>
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -17,6 +17,10 @@
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
/* for getnameinfo() : */
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
/* compile with -DUPNPC_USE_SELECT to enable upnpc_select_fds() function */
#include "miniupnpc-async.h"
#include "upnpreplyparse.h"
@ -30,8 +34,10 @@ enum methods {
int main(int argc, char * * argv)
{
char ip_address[64];
int r, n;
upnpc_t upnp;
upnpc_device_t * device = NULL;
const char * multicastif = NULL;
enum methods next_method_to_call = EGetExternalIP;
enum methods last_method = ENothing;
@ -43,7 +49,7 @@ int main(int argc, char * * argv)
}
r = upnpc_process(&upnp);
printf("upnpc_process returned %d\n", r);
while((upnp.state != EReady) && (upnp.state != EError)) {
while(upnp.state != EUPnPError) {
int nfds;
fd_set readfds;
fd_set writefds;
@ -68,26 +74,31 @@ int main(int argc, char * * argv)
perror("select");
return 1;
}
upnpc_check_select_fds(&upnp, &readfds, &writefds);
r = upnpc_process(&upnp);
#if DEBUG
printf("upnpc_process returned %d\n", r);
#endif /* DEBUG */
if(r < 0)
break;
if(upnp.state == EReady) {
if(upnp.state == EUPnPReady) {
char * p;
printf("Process UPnP IGD Method results : HTTP %d\n", upnp.http_response_code);
if(upnp.http_response_code == 200) {
if(device == NULL) {
/* select one device */
device = upnp.device_list; /* pick up the first one */
}
printf("Process UPnP IGD Method results : HTTP %d\n", device->http_response_code);
if(device->http_response_code == 200) {
switch(last_method) {
case EGetExternalIP:
p = GetValueFromNameValueList(&upnp.soap_response_data, "NewExternalIPAddress");
p = GetValueFromNameValueList(&device->soap_response_data, "NewExternalIPAddress");
printf("ExternalIPAddress = %s\n", p);
/* p = GetValueFromNameValueList(&pdata, "errorCode");*/
break;
case EGetRates:
p = GetValueFromNameValueList(&upnp.soap_response_data, "NewLayer1DownstreamMaxBitRate");
p = GetValueFromNameValueList(&device->soap_response_data, "NewLayer1DownstreamMaxBitRate");
printf("DownStream MaxBitRate = %s\t", p);
p = GetValueFromNameValueList(&upnp.soap_response_data, "NewLayer1UpstreamMaxBitRate");
p = GetValueFromNameValueList(&device->soap_response_data, "NewLayer1UpstreamMaxBitRate");
printf("UpStream MaxBitRate = %s\n", p);
break;
case EAddPortMapping:
@ -98,10 +109,10 @@ int main(int argc, char * * argv)
}
} else {
printf("SOAP error :\n");
printf(" faultcode='%s'\n", GetValueFromNameValueList(&upnp.soap_response_data, "faultcode"));
printf(" faultstring='%s'\n", GetValueFromNameValueList(&upnp.soap_response_data, "faultstring"));
printf(" errorCode=%s\n", GetValueFromNameValueList(&upnp.soap_response_data, "errorCode"));
printf(" errorDescription='%s'\n", GetValueFromNameValueList(&upnp.soap_response_data, "errorDescription"));
printf(" faultcode='%s'\n", GetValueFromNameValueList(&device->soap_response_data, "faultcode"));
printf(" faultstring='%s'\n", GetValueFromNameValueList(&device->soap_response_data, "faultstring"));
printf(" errorCode=%s\n", GetValueFromNameValueList(&device->soap_response_data, "errorCode"));
printf(" errorDescription='%s'\n", GetValueFromNameValueList(&device->soap_response_data, "errorDescription"));
}
if(next_method_to_call == ENothing)
break;
@ -110,19 +121,24 @@ int main(int argc, char * * argv)
switch(next_method_to_call) {
case EGetExternalIP:
printf("GetExternalIPAddress\n");
upnpc_get_external_ip_address(&upnp);
upnpc_get_external_ip_address(device);
next_method_to_call = EGetRates;
break;
case EGetRates:
printf("GetCommonLinkProperties\n");
upnpc_get_link_layer_max_rate(&upnp);
upnpc_get_link_layer_max_rate(device);
next_method_to_call = EAddPortMapping;
break;
case EAddPortMapping:
if(getnameinfo((struct sockaddr *)&device->selfaddr, device->selfaddrlen,
ip_address, sizeof(ip_address), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
fprintf(stderr, "getnameinfo() failed\n");
}
printf("our IP address is %s\n", ip_address);
printf("AddPortMapping\n");
upnpc_add_port_mapping(&upnp,
upnpc_add_port_mapping(device,
NULL /* remote_host */, 40002 /* ext_port */,
42042 /* int_port */, "192.168.1.202" /* int_client */,
42042 /* int_port */, ip_address /* int_client */,
"TCP" /* proto */, "this is a test" /* description */,
0 /* lease duration */);
next_method_to_call = ENothing;

View File

@ -1,6 +1,9 @@
$Id: Changelog.txt,v 1.226 2016/12/16 08:57:19 nanard Exp $
miniUPnP client Changelog.
2017/05/05:
Fix CVE-2017-8798 Thanks to tin/Team OSTStrom
2016/11/11:
check strlen before memcmp in XML parsing portlistingparse.c
fix build under SOLARIS and CYGWIN

View File

@ -2,7 +2,7 @@
/* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2016 Thomas Bernard
* Copyright (c) 2005-2017 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
@ -111,7 +111,7 @@ getHTTPResponse(int s, int * size, int * status_code)
chunksize_buf[0] = '\0';
chunksize_buf_index = 0;
while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0)
while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0)
{
if(endofheaders == 0)
{
@ -284,11 +284,12 @@ getHTTPResponse(int s, int * size, int * status_code)
goto end_of_stream;
}
}
bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
/* it is guaranteed that (n >= i) */
bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i);
if((content_buf_used + bytestocopy) > content_buf_len)
{
char * tmp;
if(content_length >= (int)(content_buf_used + bytestocopy)) {
if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) {
content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + bytestocopy;
@ -313,14 +314,15 @@ getHTTPResponse(int s, int * size, int * status_code)
{
/* not chunked */
if(content_length > 0
&& (int)(content_buf_used + n) > content_length) {
&& (content_buf_used + n) > (unsigned int)content_length) {
/* skipping additional bytes */
n = content_length - content_buf_used;
}
if(content_buf_used + n > content_buf_len)
{
char * tmp;
if(content_length >= (int)(content_buf_used + n)) {
if(content_length >= 0
&& (unsigned int)content_length >= (content_buf_used + n)) {
content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + n;
@ -340,7 +342,7 @@ getHTTPResponse(int s, int * size, int * status_code)
}
}
/* use the Content-Length header value if available */
if(content_length > 0 && (int)content_buf_used >= content_length)
if(content_length > 0 && content_buf_used >= (unsigned int)content_length)
{
#ifdef DEBUG
printf("End of HTTP content\n");

View File

@ -1,7 +1,7 @@
/* $Id: upnpc.c,v 1.114 2016/01/22 15:04:23 nanard Exp $ */
/* $Id: upnpc.c,v 1.117 2017/05/26 15:26:55 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2016 Thomas Bernard
* Copyright (c) 2005-2017 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
@ -578,8 +578,8 @@ int main(int argc, char ** argv)
}
#endif
printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING);
printf(" (c) 2005-2016 Thomas Bernard.\n");
printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
printf(" (c) 2005-2017 Thomas Bernard.\n");
printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n"
"for more information.\n");
/* command line processing */
for(i=1; i<argc; i++)

View File

@ -1,4 +1,8 @@
$Id: Changelog.txt,v 1.430 2016/12/16 09:14:40 nanard Exp $
$Id: Changelog.txt,v 1.432 2017/05/24 22:47:53 nanard Exp $
2017/05/24:
get SSDP packet receiving interface index and use it to check if the
packet is from a LAN
2017/03/13:
default to client address for AddPortMapping when <NewInternalClient>

View File

@ -1,7 +1,7 @@
MiniUPnP project.
(c) 2006-2016 Thomas Bernard
(c) 2006-2017 Thomas Bernard
Homepage : http://miniupnp.free.fr/
Mirror: http://miniupnp.tuxfamily.org/
Mirror: https://miniupnp.tuxfamily.org/
github: https://github.com/miniupnp/miniupnp
miniupnpd is still under active developpement. This documentation is

View File

@ -1,5 +1,5 @@
MiniUPnPd
Copyright (c) 2006-2016, Thomas BERNARD
Copyright (c) 2006-2017, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
MiniUPnP project
(c) 2006-2016 Thomas Bernard
webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
(c) 2006-2017 Thomas Bernard
webpage: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
github: https://github.com/miniupnp/miniupnp
freecode: http://freecode.com/projects/miniupnp
contact: miniupnp@free.fr
@ -31,7 +31,7 @@ Read the INSTALL file for instructions to compile, install and
configure miniupnpd on your system.
Report bugs to miniupnp@free.fr or on the web forum
http://miniupnp.tuxfamily.org/forum/
https://miniupnp.tuxfamily.org/forum/
or using https://github.com/miniupnp/miniupnp/issues
Thomas Bernard

View File

@ -1,4 +1,4 @@
/* $Id: minissdp.c,v 1.77 2015/08/26 07:36:52 nanard Exp $ */
/* $Id: minissdp.c,v 1.87 2017/05/24 22:33:33 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2017 Thomas Bernard
@ -16,6 +16,13 @@
#include <errno.h>
#include <syslog.h>
#ifdef IP_RECVIF
#include <sys/types.h>
#include <sys/uio.h>
#include <net/if.h>
#include <net/if_dl.h>
#endif
#include "config.h"
#if defined(ENABLE_IPV6) && defined(UPNP_STRICT)
#include <ifaddrs.h>
@ -153,7 +160,7 @@ OpenAndConfSSDPReceiveSocket(int ipv6)
struct sockaddr_storage sockname;
socklen_t sockname_len;
struct lan_addr_s * lan_addr;
int j = 1;
const int on = 1;
if( (s = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0)) < 0)
{
@ -185,10 +192,36 @@ OpenAndConfSSDPReceiveSocket(int ipv6)
sockname_len = sizeof(struct sockaddr_in);
}
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j)) < 0)
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
syslog(LOG_WARNING, "setsockopt(udp, SO_REUSEADDR): %m");
}
#ifdef IP_RECVIF
/* BSD */
if(!ipv6) {
if(setsockopt(s, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)
{
syslog(LOG_WARNING, "setsockopt(udp, IP_RECVIF): %m");
}
}
#endif /* IP_RECVIF */
#ifdef IP_PKTINFO
/* Linux */
if(!ipv6) {
if(setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)) < 0)
{
syslog(LOG_WARNING, "setsockopt(udp, IP_PKTINFO): %m");
}
}
#endif /* IP_PKTINFO */
#if defined(ENABLE_IPV6) && defined(IPV6_RECVPKTINFO)
if(ipv6) {
if(setsockopt(s, IPPROTO_IP, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0)
{
syslog(LOG_WARNING, "setsockopt(udp, IPV6_RECVPKTINFO): %m");
}
}
#endif /* defined(ENABLE_IPV6) && defined(IPV6_RECVPKTINFO) */
if(!set_non_blocking(s))
{
@ -814,17 +847,53 @@ ProcessSSDPRequest(int s, unsigned short http_port)
{
int n;
char bufr[1500];
socklen_t len_r;
#ifdef ENABLE_IPV6
struct sockaddr_storage sendername;
len_r = sizeof(struct sockaddr_storage);
#else
struct sockaddr_in sendername;
len_r = sizeof(struct sockaddr_in);
#endif
int source_ifindex = -1;
#ifdef IP_PKTINFO
char cmbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct iovec iovec = {
.iov_base = bufr,
.iov_len = sizeof(bufr)
};
struct msghdr mh = {
.msg_name = &sendername,
.msg_namelen = sizeof(sendername),
.msg_iov = &iovec,
.msg_iovlen = 1,
.msg_control = cmbuf,
.msg_controllen = sizeof(cmbuf)
};
struct cmsghdr *cmptr;
#endif /* IP_PKTINFO */
#ifdef IP_RECVIF
char cmbuf[CMSG_SPACE(sizeof(struct sockaddr_dl))];
struct iovec iovec = {
.iov_base = bufr,
.iov_len = sizeof(bufr)
};
struct msghdr mh = {
.msg_name = &sendername,
.msg_namelen = sizeof(sendername),
.msg_iov = &iovec,
.msg_iovlen = 1,
.msg_control = cmbuf,
.msg_controllen = sizeof(cmbuf)
};
struct cmsghdr *cmptr;
#endif /* IP_RECVIF */
#if defined(IP_RECVIF) || defined(IP_PKTINFO)
n = recvmsg(s, &mh, 0);
#else
socklen_t len_r;
len_r = sizeof(sendername);
n = recvfrom(s, bufr, sizeof(bufr), 0,
(struct sockaddr *)&sendername, &len_r);
#endif /* defined(IP_RECVIF) || defined(IP_PKTINFO) */
if(n < 0)
{
/* EAGAIN, EWOULDBLOCK, EINTR : silently ignore (try again next time)
@ -837,11 +906,45 @@ ProcessSSDPRequest(int s, unsigned short http_port)
}
return;
}
#if defined(IP_RECVIF) || defined(IP_PKTINFO)
for(cmptr = CMSG_FIRSTHDR(&mh); cmptr != NULL; cmptr = CMSG_NXTHDR(&mh, cmptr))
{
syslog(LOG_DEBUG, "level=%d type=%d", cmptr->cmsg_level, cmptr->cmsg_type);
#ifdef IP_PKTINFO
if(cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{
struct in_pktinfo * pi; /* fields : ifindex, spec_dst, addr */
pi = (struct in_pktinfo *)CMSG_DATA(cmptr);
syslog(LOG_DEBUG, "ifindex = %u %s", pi->ipi_ifindex, inet_ntoa(pi->ipi_spec_dst));
source_ifindex = pi->ipi_ifindex;
}
#endif /* IP_PKTINFO */
#if defined(ENABLE_IPV6) && defined(IPV6_RECVPKTINFO)
if(cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == IPV6_RECVPKTINFO)
{
struct in6_pktinfo * pi6; /* fields : ifindex, addr */
pi6 = (struct in6_pktinfo *)CMSG_DATA(cmptr);
syslog(LOG_DEBUG, "ifindex = %u", pi6->ipi6_ifindex);
source_ifindex = pi6->ipi6_ifindex;
}
#endif /* defined(ENABLE_IPV6) && defined(IPV6_RECVPKTINFO) */
#ifdef IP_RECVIF
if(cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
{
struct sockaddr_dl *sdl; /* fields : len, family, index, type, nlen, alen, slen, data */
sdl = (struct sockaddr_dl *)CMSG_DATA(cmptr);
syslog(LOG_DEBUG, "sdl_index = %d %s", sdl->sdl_index, link_ntoa(sdl));
source_ifindex = sdl->sdl_index;
}
#endif /* IP_RECVIF */
}
#endif /* defined(IP_RECVIF) || defined(IP_PKTINFO) */
#ifdef ENABLE_HTTPS
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername,
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername, source_ifindex,
http_port, https_port);
#else
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername,
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername, source_ifindex,
http_port);
#endif
@ -850,12 +953,12 @@ ProcessSSDPRequest(int s, unsigned short http_port)
#ifdef ENABLE_HTTPS
void
ProcessSSDPData(int s, const char *bufr, int n,
const struct sockaddr * sender,
const struct sockaddr * sender, int source_if,
unsigned short http_port, unsigned short https_port)
#else
void
ProcessSSDPData(int s, const char *bufr, int n,
const struct sockaddr * sender,
const struct sockaddr * sender, int source_if,
unsigned short http_port)
#endif
{
@ -889,10 +992,31 @@ ProcessSSDPData(int s, const char *bufr, int n,
/* get the string representation of the sender address */
sockaddr_to_string(sender, sender_str, sizeof(sender_str));
lan_addr = get_lan_for_peer(sender);
if(source_if >= 0)
{
if(lan_addr != NULL)
{
if(lan_addr->index != (unsigned)source_if)
{
syslog(LOG_WARNING, "interface index not matching %u != %d", lan_addr->index, source_if);
}
}
else
{
/* use the interface index */
for(lan_addr = lan_addrs.lh_first;
lan_addr != NULL;
lan_addr = lan_addr->list.le_next)
{
if(lan_addr->index == (unsigned)source_if)
break;
}
}
}
if(lan_addr == NULL)
{
syslog(LOG_WARNING, "SSDP packet sender %s not from a LAN, ignoring",
sender_str);
syslog(LOG_WARNING, "SSDP packet sender %s (if_index=%d) not from a LAN, ignoring",
sender_str, source_if);
return;
}

View File

@ -1,7 +1,7 @@
/* $Id: minissdp.h,v 1.12 2014/04/09 07:20:59 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2014 Thomas Bernard
* (c) 2006-2017 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef MINISSDP_H_INCLUDED
@ -39,12 +39,12 @@ ProcessSSDPRequest(int s, unsigned short http_port);
#ifdef ENABLE_HTTPS
void
ProcessSSDPData(int s, const char *bufr, int n,
const struct sockaddr * sendername,
const struct sockaddr * sendername, int source_if,
unsigned short http_port, unsigned short https_port);
#else
void
ProcessSSDPData(int s, const char *bufr, int n,
const struct sockaddr * sendername,
const struct sockaddr * sendername, int source_if,
unsigned short http_port);
#endif

View File

@ -631,7 +631,7 @@ static int nfqueue_cb(
/* printf("pkt found %s\n",dd);*/
ProcessSSDPData (sudp, dd, size - x,
&sendername, (unsigned short) 5555);
&sendername, -1, (unsigned short) 5555);
}
}
}
@ -984,7 +984,6 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str)
}
}
#endif
#ifdef ENABLE_IPV6
if(lan_addr->ifname[0] != '\0')
{
lan_addr->index = if_nametoindex(lan_addr->ifname);
@ -992,6 +991,7 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str)
fprintf(stderr, "Cannot get index for network interface %s",
lan_addr->ifname);
}
#ifdef ENABLE_IPV6
else
{
fprintf(stderr,

View File

@ -16,9 +16,7 @@
* with ascii representation and mask */
struct lan_addr_s {
char ifname[IFNAMSIZ]; /* example: eth0 */
#ifdef ENABLE_IPV6
unsigned int index; /* use if_nametoindex() */
#endif
char str[16]; /* example: 192.168.0.1 */
struct in_addr addr, mask; /* ip/mask */
#ifdef MULTIPLE_EXTERNAL_IP