Merge branch 'master' into search_all

Conflicts:
	miniupnpc/apiversions.txt
This commit is contained in:
Thomas Bernard 2014-11-17 10:29:29 +01:00
commit e60c3a8ce5
10 changed files with 158 additions and 31 deletions

3
README
View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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,15 +18,21 @@
#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);*/
if(base != NULL)
event_base_loopbreak(base);
}
@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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 \

View File

@ -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 11
API version 12
miniupnpc.h :
add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices()
functions
updated macros :
#define MINIUPNPC_API_VERSION 12
API version 11
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

View File

@ -19,7 +19,7 @@
/* versions : */
#define MINIUPNPC_VERSION "1.9"
#define MINIUPNPC_API_VERSION 11
#define MINIUPNPC_API_VERSION 12
#ifdef __cplusplus
extern "C" {

View File

@ -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;
@ -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;
}