miniupnpc: parseURL()/miniwget() : IPv6 addresses scope
This commit is contained in:
parent
0e85a91784
commit
c585986d2f
|
@ -4,6 +4,8 @@ miniUPnP client Changelog.
|
||||||
2012/06/23:
|
2012/06/23:
|
||||||
More error return checks in upnpc.c
|
More error return checks in upnpc.c
|
||||||
#define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
|
#define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
|
||||||
|
parseURL() now parses IPv6 addresses scope
|
||||||
|
new parameter for miniwget() : IPv6 address scope
|
||||||
increment API_VERSION to 9
|
increment API_VERSION to 9
|
||||||
|
|
||||||
2012/06/20:
|
2012/06/20:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: connecthostport.c,v 1.6 2012/01/21 13:30:31 nanard Exp $ */
|
/* $Id: connecthostport.c,v 1.8 2012/06/23 22:32:33 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2010-2012 Thomas Bernard
|
* Copyright (c) 2010-2012 Thomas Bernard
|
||||||
|
@ -52,7 +52,8 @@
|
||||||
/* connecthostport()
|
/* connecthostport()
|
||||||
* return a socket connected (TCP) to the host and port
|
* return a socket connected (TCP) to the host and port
|
||||||
* or -1 in case of error */
|
* or -1 in case of error */
|
||||||
int connecthostport(const char * host, unsigned short port)
|
int connecthostport(const char * host, unsigned short port,
|
||||||
|
unsigned int scope_id)
|
||||||
{
|
{
|
||||||
int s, n;
|
int s, n;
|
||||||
#ifdef USE_GETHOSTBYNAME
|
#ifdef USE_GETHOSTBYNAME
|
||||||
|
@ -145,10 +146,12 @@ int connecthostport(const char * host, unsigned short port)
|
||||||
if(host[0] == '[')
|
if(host[0] == '[')
|
||||||
{
|
{
|
||||||
/* literal ip v6 address */
|
/* literal ip v6 address */
|
||||||
int i;
|
int i, j;
|
||||||
for(i = 0; host[i+1] && (host[i+1] != ']') && i < MAXHOSTNAMELEN; i++)
|
for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
|
||||||
{
|
{
|
||||||
tmp_host[i] = host[i+1];
|
tmp_host[i] = host[j];
|
||||||
|
if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */
|
||||||
|
j+=2; /* skip "25" */
|
||||||
}
|
}
|
||||||
tmp_host[i] = '\0';
|
tmp_host[i] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -173,6 +176,10 @@ int connecthostport(const char * host, unsigned short port)
|
||||||
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
continue;
|
continue;
|
||||||
|
if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
|
||||||
|
struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
|
||||||
|
addr6->sin6_scope_id = scope_id;
|
||||||
|
}
|
||||||
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||||
/* setting a 3 seconds timeout for the connect() call */
|
/* setting a 3 seconds timeout for the connect() call */
|
||||||
timeout.tv_sec = 3;
|
timeout.tv_sec = 3;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* $Id: connecthostport.h,v 1.1 2010/04/04 23:21:03 nanard Exp $ */
|
/* $Id: connecthostport.h,v 1.2 2012/06/23 22:32:33 nanard Exp $ */
|
||||||
/* Project: miniupnp
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
* Copyright (c) 2010 Thomas Bernard
|
* Copyright (c) 2010-2012 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 __CONNECTHOSTPORT_H__
|
#ifndef __CONNECTHOSTPORT_H__
|
||||||
|
@ -11,7 +11,8 @@
|
||||||
/* connecthostport()
|
/* connecthostport()
|
||||||
* return a socket connected (TCP) to the host and port
|
* return a socket connected (TCP) to the host and port
|
||||||
* or -1 in case of error */
|
* or -1 in case of error */
|
||||||
int connecthostport(const char * host, unsigned short port);
|
int connecthostport(const char * host, unsigned short port,
|
||||||
|
unsigned int scope_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: miniupnpc.c,v 1.106 2012/06/11 16:08:17 nanard Exp $ */
|
/* $Id: miniupnpc.c,v 1.107 2012/06/23 22:36:35 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Web : http://miniupnp.free.fr/
|
* Web : http://miniupnp.free.fr/
|
||||||
* Author : Thomas BERNARD
|
* Author : Thomas BERNARD
|
||||||
|
@ -189,12 +189,11 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service,
|
||||||
strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
|
strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
|
||||||
soapbody + sizeof(soapbody) - p);
|
soapbody + sizeof(soapbody) - p);
|
||||||
}
|
}
|
||||||
if(!parseURL(url, hostname, &port, &path)) return NULL;
|
if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
|
||||||
if(s<0)
|
if(s < 0) {
|
||||||
{
|
s = connecthostport(hostname, port, 0);
|
||||||
s = connecthostport(hostname, port);
|
if(s < 0) {
|
||||||
if(s < 0)
|
/* failed to connect */
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,6 +685,7 @@ upnpDiscover(int delay, const char * multicastif,
|
||||||
tmp->buffer[urlsize] = '\0';
|
tmp->buffer[urlsize] = '\0';
|
||||||
memcpy(tmp->buffer + urlsize + 1, st, stsize);
|
memcpy(tmp->buffer + urlsize + 1, st, stsize);
|
||||||
tmp->buffer[urlsize+1+stsize] = '\0';
|
tmp->buffer[urlsize+1+stsize] = '\0';
|
||||||
|
tmp->scope_id = scope_id;
|
||||||
devlist = tmp;
|
devlist = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -873,7 +873,8 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
||||||
if(state == 1)
|
if(state == 1)
|
||||||
{
|
{
|
||||||
desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
|
desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
|
||||||
lanaddr, lanaddrlen);
|
lanaddr, lanaddrlen,
|
||||||
|
dev->scope_id);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if(!desc[i].xml)
|
if(!desc[i].xml)
|
||||||
{
|
{
|
||||||
|
@ -944,7 +945,7 @@ 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);
|
lanaddr, lanaddrlen, 0);
|
||||||
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));
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct UPNPDev {
|
||||||
struct UPNPDev * pNext;
|
struct UPNPDev * pNext;
|
||||||
char * descURL;
|
char * descURL;
|
||||||
char * st;
|
char * st;
|
||||||
|
unsigned int scope_id;
|
||||||
char buffer[2];
|
char buffer[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: miniwget.c,v 1.56 2012/05/01 16:16:08 nanard Exp $ */
|
/* $Id: miniwget.c,v 1.57 2012/06/23 22:35:58 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Website : http://miniupnp.free.fr/
|
* Website : http://miniupnp.free.fr/
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
|
@ -36,6 +36,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
||||||
|
@ -289,7 +290,7 @@ 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)
|
const char * httpversion, unsigned int scope_id)
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
int s;
|
int s;
|
||||||
|
@ -299,7 +300,7 @@ miniwget3(const char * host,
|
||||||
void * content;
|
void * content;
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
s = connecthostport(host, port);
|
s = connecthostport(host, port, scope_id);
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -392,22 +393,27 @@ miniwget3(const char * host,
|
||||||
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)
|
||||||
{
|
{
|
||||||
char * respbuffer;
|
char * respbuffer;
|
||||||
|
|
||||||
respbuffer = miniwget3(host, port, path, size, addr_str, addr_str_len, "1.1");
|
#if 1
|
||||||
/*
|
respbuffer = miniwget3(host, port, path, size,
|
||||||
respbuffer = miniwget3(host, port, path, size, addr_str, addr_str_len, "1.0");
|
addr_str, addr_str_len, "1.1", scope_id);
|
||||||
|
#else
|
||||||
|
respbuffer = miniwget3(host, port, path, size,
|
||||||
|
addr_str, addr_str_len, "1.0", scope_id);
|
||||||
if (*size == 0)
|
if (*size == 0)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Retrying with HTTP/1.1\n");
|
printf("Retrying with HTTP/1.1\n");
|
||||||
#endif
|
#endif
|
||||||
free(respbuffer);
|
free(respbuffer);
|
||||||
respbuffer = miniwget3(host, port, path, size, addr_str, addr_str_len, "1.1");
|
respbuffer = miniwget3(host, port, path, size,
|
||||||
|
addr_str, addr_str_len, "1.1", scope_id);
|
||||||
}
|
}
|
||||||
*/
|
#endif
|
||||||
return respbuffer;
|
return respbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +430,10 @@ miniwget2(const char * host,
|
||||||
* Return values :
|
* Return values :
|
||||||
* 0 - Failure
|
* 0 - Failure
|
||||||
* 1 - Success */
|
* 1 - Success */
|
||||||
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
|
int
|
||||||
|
parseURL(const char * url,
|
||||||
|
char * hostname, unsigned short * port,
|
||||||
|
char * * path, unsigned int * scope_id)
|
||||||
{
|
{
|
||||||
char * p1, *p2, *p3;
|
char * p1, *p2, *p3;
|
||||||
if(!url)
|
if(!url)
|
||||||
|
@ -440,7 +449,29 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
|
||||||
if(*p1 == '[')
|
if(*p1 == '[')
|
||||||
{
|
{
|
||||||
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
|
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
|
||||||
|
char * scope;
|
||||||
|
scope = strchr(p1, '%');
|
||||||
p2 = strchr(p1, ']');
|
p2 = strchr(p1, ']');
|
||||||
|
if(p2 && scope && scope < p2 && scope_id) {
|
||||||
|
/* parse scope */
|
||||||
|
#ifdef IF_NAMESIZE
|
||||||
|
char tmp[IF_NAMESIZE];
|
||||||
|
int l;
|
||||||
|
scope++;
|
||||||
|
/* "%25" is just '%' in URL encoding */
|
||||||
|
if(scope[0] == '2' && scope[1] == '5')
|
||||||
|
scope += 2; /* skip "25" */
|
||||||
|
l = p2 - scope;
|
||||||
|
if(l >= IF_NAMESIZE)
|
||||||
|
l = IF_NAMESIZE - 1;
|
||||||
|
memcpy(tmp, scope, l);
|
||||||
|
tmp[l] = '\0';
|
||||||
|
*scope_id = if_nametoindex(tmp);
|
||||||
|
if(*scope_id == 0) {
|
||||||
|
*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
p3 = strchr(p1, '/');
|
p3 = strchr(p1, '/');
|
||||||
if(p2 && p3)
|
if(p2 && p3)
|
||||||
{
|
{
|
||||||
|
@ -490,22 +521,26 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * miniwget(const char * url, int * size)
|
void *
|
||||||
|
miniwget(const char * url, int * size, unsigned int scope_id)
|
||||||
{
|
{
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
char * path;
|
char * path;
|
||||||
/* protocol://host:port/chemin */
|
/* protocol://host:port/chemin */
|
||||||
char hostname[MAXHOSTNAMELEN+1];
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
*size = 0;
|
*size = 0;
|
||||||
if(!parseURL(url, hostname, &port, &path))
|
if(!parseURL(url, hostname, &port, &path, &scope_id))
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
|
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
|
||||||
|
hostname, port, path, scope_id);
|
||||||
#endif
|
#endif
|
||||||
return miniwget2(hostname, port, path, size, 0, 0);
|
return miniwget2(hostname, port, path, size, 0, 0, scope_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
|
void *
|
||||||
|
miniwget_getaddr(const char * url, int * size,
|
||||||
|
char * addr, int addrlen, unsigned int scope_id)
|
||||||
{
|
{
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
char * path;
|
char * path;
|
||||||
|
@ -514,11 +549,12 @@ void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
|
||||||
*size = 0;
|
*size = 0;
|
||||||
if(addr)
|
if(addr)
|
||||||
addr[0] = '\0';
|
addr[0] = '\0';
|
||||||
if(!parseURL(url, hostname, &port, &path))
|
if(!parseURL(url, hostname, &port, &path, &scope_id))
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
|
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
|
||||||
|
hostname, port, path, scope_id);
|
||||||
#endif
|
#endif
|
||||||
return miniwget2(hostname, port, path, size, addr, addrlen);
|
return miniwget2(hostname, port, path, size, addr, addrlen, scope_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* $Id: miniwget.h,v 1.6 2010/12/09 16:11:33 nanard Exp $ */
|
/* $Id: miniwget.h,v 1.7 2012/06/23 22:35:59 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005 Thomas Bernard
|
* Copyright (c) 2005-2012 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.
|
||||||
* */
|
* */
|
||||||
|
@ -16,11 +16,11 @@ extern "C" {
|
||||||
|
|
||||||
LIBSPEC void * getHTTPResponse(int s, int * size);
|
LIBSPEC void * getHTTPResponse(int s, int * size);
|
||||||
|
|
||||||
LIBSPEC void * miniwget(const char *, int *);
|
LIBSPEC void * miniwget(const char *, int *, unsigned int);
|
||||||
|
|
||||||
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
|
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int);
|
||||||
|
|
||||||
int parseURL(const char *, char *, unsigned short *, char * *);
|
int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* $Id: testminiwget.c,v 1.3 2011/05/06 16:33:53 nanard Exp $ */
|
/* $Id: testminiwget.c,v 1.4 2012/06/23 22:35:59 nanard Exp $ */
|
||||||
/* Project : miniupnp
|
/* Project : miniupnp
|
||||||
* Author : Thomas Bernard
|
* Author : Thomas Bernard
|
||||||
* Copyright (c) 2005-2011 Thomas Bernard
|
* Copyright (c) 2005-2012 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,13 +20,13 @@ int main(int argc, char * * argv)
|
||||||
int size, writtensize;
|
int size, writtensize;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char addr[64];
|
char addr[64];
|
||||||
|
|
||||||
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(argv[1], &size);*/
|
data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr), 0);
|
||||||
data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr));
|
|
||||||
if(!data) {
|
if(!data) {
|
||||||
fprintf(stderr, "Error fetching %s\n", argv[1]);
|
fprintf(stderr, "Error fetching %s\n", argv[1]);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue