Merge branch 'master' into search_all
Conflicts: miniupnpc/apiversions.txt
This commit is contained in:
commit
e60c3a8ce5
3
README
3
README
|
@ -10,6 +10,9 @@ 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.
|
||||
miniupnpc-async/ : Proof of concept for a UPnP IGD control point using
|
||||
asynchronous (non blocking) sockets.
|
||||
miniupnpc-libevent/ : UPnP IGD control point using libevent2 http://libevent.org/
|
||||
|
||||
Thanks to :
|
||||
* Ryan Wagoner
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: miniupnpc-libevent.c,v 1.8 2014/11/13 09:15:23 nanard Exp $ */
|
||||
/* $Id: miniupnpc-libevent.c,v 1.11 2014/11/17 09:17:38 nanard Exp $ */
|
||||
/* miniupnpc-libevent
|
||||
* Copyright (c) 2008-2014, Thomas BERNARD <miniupnp@free.fr>
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
|
@ -342,9 +342,13 @@ static void upnpc_desc_received(struct evhttp_request * req, void * pvoid)
|
|||
printIGD(&igd);
|
||||
#endif /* DEBUG */
|
||||
p->control_conn_url = build_url_string(igd.urlbase, p->root_desc_location, igd.first.controlurl);
|
||||
p->conn_service_type = strdup(igd.first.servicetype);
|
||||
p->control_cif_url = build_url_string(igd.urlbase, p->root_desc_location, igd.CIF.controlurl);
|
||||
debug_printf("control_conn_url='%s'\n", p->control_conn_url);
|
||||
debug_printf("control_cif_url='%s'\n", p->control_cif_url);
|
||||
p->cif_service_type = strdup(igd.CIF.servicetype);
|
||||
debug_printf("control_conn_url='%s'\n (service_type='%s')\n",
|
||||
p->control_conn_url, p->conn_service_type);
|
||||
debug_printf("control_cif_url='%s'\n (service_type='%s')\n",
|
||||
p->control_cif_url, p->cif_service_type);
|
||||
p->ready_cb(evhttp_request_get_response_code(req), p->cb_data);
|
||||
}
|
||||
|
||||
|
@ -592,8 +596,12 @@ int upnpc_finalize(upnpc_t * p)
|
|||
p->root_desc_location = NULL;
|
||||
free(p->control_cif_url);
|
||||
p->control_cif_url = NULL;
|
||||
free(p->cif_service_type);
|
||||
p->cif_service_type = NULL;
|
||||
free(p->control_conn_url);
|
||||
p->control_conn_url = NULL;
|
||||
free(p->conn_service_type);
|
||||
p->conn_service_type = NULL;
|
||||
if(p->ssdp_socket >= 0) {
|
||||
close(p->ssdp_socket);
|
||||
p->ssdp_socket = -1;
|
||||
|
@ -621,17 +629,39 @@ int upnpc_finalize(upnpc_t * p)
|
|||
int upnpc_get_external_ip_address(upnpc_t * p)
|
||||
{
|
||||
return upnpc_send_soap_request(p, p->control_conn_url,
|
||||
"urn:schemas-upnp-org:service:WANIPConnection:1",
|
||||
p->conn_service_type/*"urn:schemas-upnp-org:service:WANIPConnection:1"*/,
|
||||
"GetExternalIPAddress", NULL, 0);
|
||||
}
|
||||
|
||||
int upnpc_get_link_layer_max_rate(upnpc_t * p)
|
||||
{
|
||||
return upnpc_send_soap_request(p, p->control_cif_url,
|
||||
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
|
||||
p->cif_service_type/*"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"*/,
|
||||
"GetCommonLinkProperties", NULL, 0);
|
||||
}
|
||||
|
||||
int upnpc_delete_port_mapping(upnpc_t * p,
|
||||
const char * remote_host, unsigned short ext_port,
|
||||
const char * proto)
|
||||
{
|
||||
struct upnp_args args[3];
|
||||
char ext_port_str[8];
|
||||
|
||||
if(proto == NULL || ext_port == 0)
|
||||
return UPNPC_ERR_INVALID_ARGS;
|
||||
snprintf(ext_port_str, sizeof(ext_port_str), "%hu", ext_port);
|
||||
args[0].elt = "NewRemoteHost";
|
||||
args[0].val = remote_host?remote_host:"";
|
||||
args[1].elt = "NewExternalPort";
|
||||
args[1].val = ext_port_str;
|
||||
args[2].elt = "NewProtocol";
|
||||
args[2].val = proto;
|
||||
return upnpc_send_soap_request(p, p->control_conn_url,
|
||||
p->conn_service_type,/*"urn:schemas-upnp-org:service:WANIPConnection:1",*/
|
||||
"DeletePortMapping",
|
||||
args, 3);
|
||||
}
|
||||
|
||||
int upnpc_add_port_mapping(upnpc_t * p,
|
||||
const char * remote_host, unsigned short ext_port,
|
||||
unsigned short int_port, const char * int_client,
|
||||
|
@ -665,7 +695,7 @@ int upnpc_add_port_mapping(upnpc_t * p,
|
|||
args[7].elt = "NewLeaseDuration";
|
||||
args[7].val = lease_duration_str;
|
||||
return upnpc_send_soap_request(p, p->control_conn_url,
|
||||
"urn:schemas-upnp-org:service:WANIPConnection:1",
|
||||
p->conn_service_type/*"urn:schemas-upnp-org:service:WANIPConnection:1"*/,
|
||||
"AddPortMapping",
|
||||
args, 8);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: miniupnpc-libevent.h,v 1.3 2014/11/12 14:10:52 nanard Exp $ */
|
||||
/* $Id: miniupnpc-libevent.h,v 1.6 2014/11/17 09:17:38 nanard Exp $ */
|
||||
/* miniupnpc-libevent
|
||||
* Copyright (c) 2008-2014, Thomas BERNARD <miniupnp@free.fr>
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
|
@ -42,7 +42,9 @@ typedef struct {
|
|||
char * root_desc_location;
|
||||
struct evhttp_connection * desc_conn;
|
||||
char * control_cif_url;
|
||||
char * cif_service_type;
|
||||
char * control_conn_url;
|
||||
char * conn_service_type;
|
||||
struct evhttp_connection * soap_conn;
|
||||
struct NameValueParserData soap_response_data;
|
||||
upnpc_callback_fn ready_cb;
|
||||
|
@ -65,6 +67,10 @@ int upnpc_add_port_mapping(upnpc_t * p,
|
|||
const char * proto, const char * description,
|
||||
unsigned int lease_duration);
|
||||
|
||||
int upnpc_delete_port_mapping(upnpc_t * p,
|
||||
const char * remote_host, unsigned short ext_port,
|
||||
const char * proto);
|
||||
|
||||
#ifdef UPNPC_USE_SELECT
|
||||
int upnpc_select_fds(upnpc_t * p, int * nfds, fd_set * readfds, fd_set * writefds);
|
||||
#endif /* UPNPC_USE_SELECT */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: upnpc-libevent.c,v 1.5 2014/11/13 09:46:12 nanard Exp $ */
|
||||
/* $Id: upnpc-libevent.c,v 1.7 2014/11/14 11:37:45 nanard Exp $ */
|
||||
/* miniupnpc-libevent
|
||||
* Copyright (c) 2008-2014, Thomas BERNARD <miniupnp@free.fr>
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
|
@ -18,16 +18,22 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "miniupnpc-libevent.h"
|
||||
|
||||
static struct event_base *base = NULL;
|
||||
static char local_address[32];
|
||||
|
||||
static void sighandler(int signal)
|
||||
{
|
||||
(void)signal;
|
||||
/*printf("signal %d\n", signal);*/
|
||||
event_base_loopbreak(base);
|
||||
if(base != NULL)
|
||||
event_base_loopbreak(base);
|
||||
}
|
||||
|
||||
/* ready callback */
|
||||
|
@ -39,7 +45,13 @@ static void ready(int code, void * data)
|
|||
upnpc_get_external_ip_address(p);
|
||||
}
|
||||
|
||||
static enum { EGetExtIp = 0, EGetMaxRate, EAddPortMapping, EFinished } state = EGetExtIp;
|
||||
static enum {
|
||||
EGetExtIp = 0,
|
||||
EGetMaxRate,
|
||||
EAddPortMapping,
|
||||
EDeletePortMapping,
|
||||
EFinished
|
||||
} state = EGetExtIp;
|
||||
|
||||
/* soap callback */
|
||||
static void soap(int code, void * data)
|
||||
|
@ -55,11 +67,16 @@ static void soap(int code, void * data)
|
|||
break;
|
||||
case EGetMaxRate:
|
||||
printf("DownStream MaxBitRate = %s\t", GetValueFromNameValueList(&p->soap_response_data, "NewLayer1DownstreamMaxBitRate"));
|
||||
upnpc_add_port_mapping(p, NULL, 60001, 60002, "192.168.0.42", "TCP", "test port mapping", 0);
|
||||
upnpc_add_port_mapping(p, NULL, 60001, 60002, local_address, "TCP", "test port mapping", 0);
|
||||
printf("UpStream MaxBitRate = %s\n", GetValueFromNameValueList(&p->soap_response_data, "NewLayer1UpstreamMaxBitRate"));
|
||||
state = EAddPortMapping;
|
||||
break;
|
||||
case EAddPortMapping:
|
||||
printf("OK!\n");
|
||||
upnpc_delete_port_mapping(p, NULL, 60001, "TCP");
|
||||
state = EDeletePortMapping;
|
||||
break;
|
||||
case EDeletePortMapping:
|
||||
printf("OK!\n");
|
||||
state = EFinished;
|
||||
default:
|
||||
|
@ -75,6 +92,51 @@ static void soap(int code, void * data)
|
|||
}
|
||||
}
|
||||
|
||||
/* use a UDP "connection" to 8.8.8.8
|
||||
* to retrieve local address */
|
||||
int find_local_address(void)
|
||||
{
|
||||
int s;
|
||||
struct sockaddr_in local, remote;
|
||||
socklen_t len;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(s < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
memset(&remote, 0, sizeof(remote));
|
||||
/* bind to local port 4567 */
|
||||
local.sin_family = AF_INET;
|
||||
local.sin_port = htons(4567);
|
||||
local.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if(bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) {
|
||||
perror("bind");
|
||||
return -1;
|
||||
}
|
||||
/* "connect" google's DNS server at 8.8.8.8 port 4567 */
|
||||
remote.sin_family = AF_INET;
|
||||
remote.sin_port = htons(4567);
|
||||
remote.sin_addr.s_addr = inet_addr("8.8.8.8");
|
||||
if(connect(s, (struct sockaddr *)&remote, sizeof(remote)) < 0) {
|
||||
perror("connect");
|
||||
return -1;
|
||||
}
|
||||
len = sizeof(local);
|
||||
if(getsockname(s, (struct sockaddr *)&local, &len) < 0) {
|
||||
perror("getsockname");
|
||||
return -1;
|
||||
}
|
||||
if(inet_ntop(AF_INET, &(local.sin_addr), local_address, sizeof(local_address)) == NULL) {
|
||||
perror("inet_ntop");
|
||||
return -1;
|
||||
}
|
||||
printf("local address : %s\n", local_address);
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* program entry point */
|
||||
|
||||
|
@ -93,6 +155,11 @@ int main(int argc, char * * argv)
|
|||
if(sigaction(SIGINT, &sa, NULL) < 0) {
|
||||
perror("sigaction");
|
||||
}
|
||||
|
||||
if(find_local_address() < 0) {
|
||||
fprintf(stderr, "failed to get local address\n");
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
event_enable_debug_mode();
|
||||
#if LIBEVENT_VERSION_NUMBER >= 0x02010100
|
||||
|
|
|
@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6)
|
|||
|
||||
project (miniupnpc C)
|
||||
set (MINIUPNPC_VERSION 1.9)
|
||||
set (MINIUPNPC_API_VERSION 11)
|
||||
set (MINIUPNPC_API_VERSION 12)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
if (WIN32)
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
$Id: Changelog.txt,v 1.199 2014/11/05 06:06:37 nanard Exp $
|
||||
miniUPnP client Changelog.
|
||||
|
||||
2014/11/17:
|
||||
search all :
|
||||
upnpDiscoverDevices() / upnpDiscoverAll() functions
|
||||
listdevices executable
|
||||
increment API_VERSION to 12
|
||||
|
||||
2014/11/13:
|
||||
increment API_VERSION to 11
|
||||
|
||||
2014/11/05:
|
||||
simplified function GetUPNPUrls()
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ ifeq (SunOS, $(OS))
|
|||
endif
|
||||
|
||||
# APIVERSION is used to build SONAME
|
||||
APIVERSION = 11
|
||||
APIVERSION = 12
|
||||
|
||||
SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \
|
||||
upnpc.c upnpcommands.c upnpreplyparse.c testminixml.c \
|
||||
|
|
|
@ -2,10 +2,21 @@ $Id: apiversions.txt,v 1.3 2014/01/31 13:14:32 nanard Exp $
|
|||
|
||||
Differences in API between miniUPnPc versions
|
||||
|
||||
API version 12
|
||||
miniupnpc.h :
|
||||
add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices()
|
||||
functions
|
||||
updated macros :
|
||||
#define MINIUPNPC_API_VERSION 12
|
||||
|
||||
API version 11
|
||||
|
||||
add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices()
|
||||
functions
|
||||
upnpreplyparse.h / portlistingparse.h :
|
||||
removed usage of sys/queue.h / bsdqueue.h
|
||||
|
||||
miniupnpc.h:
|
||||
updated macros :
|
||||
#define MINIUPNPC_API_VERSION 11
|
||||
|
||||
====================== miniUPnPc version 1.9 ======================
|
||||
API version 10
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
/* versions : */
|
||||
#define MINIUPNPC_VERSION "1.9"
|
||||
#define MINIUPNPC_API_VERSION 11
|
||||
#define MINIUPNPC_API_VERSION 12
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
/* $Id: receivedata.c,v 1.4 2012/06/23 22:34:47 nanard Exp $ */
|
||||
/* $Id: receivedata.c,v 1.6 2014/11/13 13:51:52 nanard Exp $ */
|
||||
/* Project : miniupnp
|
||||
* Website : http://miniupnp.free.fr/
|
||||
* Author : Thomas Bernard
|
||||
* Copyright (c) 2011-2012 Thomas Bernard
|
||||
* Copyright (c) 2011-2014 Thomas Bernard
|
||||
* This software is subject to the conditions detailed in the
|
||||
* LICENCE file provided in this distribution. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#else /* _WIN32 */
|
||||
#include <unistd.h>
|
||||
#if defined(__amigaos__) && !defined(__amigaos4__)
|
||||
#define socklen_t int
|
||||
|
@ -21,10 +22,10 @@
|
|||
#include <netinet/in.h>
|
||||
#if !defined(__amigaos__) && !defined(__amigaos4__)
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||
#include <errno.h>
|
||||
#define MINIUPNPC_IGNORE_EINTR
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
|
||||
|
@ -42,20 +43,20 @@ receivedata(int socket,
|
|||
#if MINIUPNPC_GET_SRC_ADDR
|
||||
struct sockaddr_storage src_addr;
|
||||
socklen_t src_addr_len = sizeof(src_addr);
|
||||
#endif
|
||||
#endif /* MINIUPNPC_GET_SRC_ADDR */
|
||||
int n;
|
||||
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
|
||||
/* using poll */
|
||||
struct pollfd fds[1]; /* for the poll */
|
||||
#ifdef MINIUPNPC_IGNORE_EINTR
|
||||
do {
|
||||
#endif
|
||||
#endif /* MINIUPNPC_IGNORE_EINTR */
|
||||
fds[0].fd = socket;
|
||||
fds[0].events = POLLIN;
|
||||
n = poll(fds, 1, timeout);
|
||||
#ifdef MINIUPNPC_IGNORE_EINTR
|
||||
} while(n < 0 && errno == EINTR);
|
||||
#endif
|
||||
#endif /* MINIUPNPC_IGNORE_EINTR */
|
||||
if(n < 0) {
|
||||
PRINT_SOCKET_ERROR("poll");
|
||||
return -1;
|
||||
|
@ -63,7 +64,7 @@ receivedata(int socket,
|
|||
/* timeout */
|
||||
return 0;
|
||||
}
|
||||
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||
/* using select under _WIN32 and amigaos */
|
||||
fd_set socketSet;
|
||||
TIMEVAL timeval;
|
||||
|
@ -78,13 +79,14 @@ receivedata(int socket,
|
|||
} else if(n == 0) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
|
||||
#if MINIUPNPC_GET_SRC_ADDR
|
||||
memset(&src_addr, 0, sizeof(src_addr));
|
||||
n = recvfrom(socket, data, length, 0,
|
||||
(struct sockaddr *)&src_addr, &src_addr_len);
|
||||
#else
|
||||
#else /* MINIUPNPC_GET_SRC_ADDR */
|
||||
n = recv(socket, data, length, 0);
|
||||
#endif
|
||||
#endif /* MINIUPNPC_GET_SRC_ADDR */
|
||||
if(n<0) {
|
||||
PRINT_SOCKET_ERROR("recv");
|
||||
}
|
||||
|
@ -93,12 +95,11 @@ receivedata(int socket,
|
|||
const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
|
||||
#ifdef DEBUG
|
||||
printf("scope_id=%u\n", src_addr6->sin6_scope_id);
|
||||
#endif
|
||||
#endif /* DEBUG */
|
||||
if(scope_id)
|
||||
*scope_id = src_addr6->sin6_scope_id;
|
||||
}
|
||||
#endif
|
||||
#endif /* MINIUPNPC_GET_SRC_ADDR */
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue