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:
|
||||
More error return checks in upnpc.c
|
||||
#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
|
||||
|
||||
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
|
||||
* Author : Thomas Bernard
|
||||
* Copyright (c) 2010-2012 Thomas Bernard
|
||||
|
@ -52,7 +52,8 @@
|
|||
/* connecthostport()
|
||||
* return a socket connected (TCP) to the host and port
|
||||
* 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;
|
||||
#ifdef USE_GETHOSTBYNAME
|
||||
|
@ -145,10 +146,12 @@ int connecthostport(const char * host, unsigned short port)
|
|||
if(host[0] == '[')
|
||||
{
|
||||
/* literal ip v6 address */
|
||||
int i;
|
||||
for(i = 0; host[i+1] && (host[i+1] != ']') && i < MAXHOSTNAMELEN; i++)
|
||||
int i, j;
|
||||
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';
|
||||
}
|
||||
|
@ -173,6 +176,10 @@ int connecthostport(const char * host, unsigned short port)
|
|||
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||
if(s < 0)
|
||||
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
|
||||
/* setting a 3 seconds timeout for the connect() call */
|
||||
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
|
||||
* http://miniupnp.free.fr/
|
||||
* Author: Thomas Bernard
|
||||
* Copyright (c) 2010 Thomas Bernard
|
||||
* Copyright (c) 2010-2012 Thomas Bernard
|
||||
* This software is subjects to the conditions detailed
|
||||
* in the LICENCE file provided within this distribution */
|
||||
#ifndef __CONNECTHOSTPORT_H__
|
||||
|
@ -11,7 +11,8 @@
|
|||
/* connecthostport()
|
||||
* return a socket connected (TCP) to the host and port
|
||||
* 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
|
||||
|
||||
|
|
|
@ -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
|
||||
* Web : http://miniupnp.free.fr/
|
||||
* 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",
|
||||
soapbody + sizeof(soapbody) - p);
|
||||
}
|
||||
if(!parseURL(url, hostname, &port, &path)) return NULL;
|
||||
if(s<0)
|
||||
{
|
||||
s = connecthostport(hostname, port);
|
||||
if(s < 0)
|
||||
{
|
||||
if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
|
||||
if(s < 0) {
|
||||
s = connecthostport(hostname, port, 0);
|
||||
if(s < 0) {
|
||||
/* failed to connect */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -686,6 +685,7 @@ upnpDiscover(int delay, const char * multicastif,
|
|||
tmp->buffer[urlsize] = '\0';
|
||||
memcpy(tmp->buffer + urlsize + 1, st, stsize);
|
||||
tmp->buffer[urlsize+1+stsize] = '\0';
|
||||
tmp->scope_id = scope_id;
|
||||
devlist = tmp;
|
||||
}
|
||||
}
|
||||
|
@ -873,7 +873,8 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
|||
if(state == 1)
|
||||
{
|
||||
desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
|
||||
lanaddr, lanaddrlen);
|
||||
lanaddr, lanaddrlen,
|
||||
dev->scope_id);
|
||||
#ifdef DEBUG
|
||||
if(!desc[i].xml)
|
||||
{
|
||||
|
@ -944,7 +945,7 @@ UPNP_GetIGDFromUrl(const char * rootdescurl,
|
|||
char * descXML;
|
||||
int descXMLsize = 0;
|
||||
descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
|
||||
lanaddr, lanaddrlen);
|
||||
lanaddr, lanaddrlen, 0);
|
||||
if(descXML) {
|
||||
memset(data, 0, sizeof(struct IGDdatas));
|
||||
memset(urls, 0, sizeof(struct UPNPUrls));
|
||||
|
|
|
@ -37,6 +37,7 @@ struct UPNPDev {
|
|||
struct UPNPDev * pNext;
|
||||
char * descURL;
|
||||
char * st;
|
||||
unsigned int scope_id;
|
||||
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
|
||||
* Website : http://miniupnp.free.fr/
|
||||
* Author : Thomas Bernard
|
||||
|
@ -36,6 +36,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#define closesocket close
|
||||
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
|
||||
|
@ -289,7 +290,7 @@ static void *
|
|||
miniwget3(const char * host,
|
||||
unsigned short port, const char * path,
|
||||
int * size, char * addr_str, int addr_str_len,
|
||||
const char * httpversion)
|
||||
const char * httpversion, unsigned int scope_id)
|
||||
{
|
||||
char buf[2048];
|
||||
int s;
|
||||
|
@ -299,7 +300,7 @@ miniwget3(const char * host,
|
|||
void * content;
|
||||
|
||||
*size = 0;
|
||||
s = connecthostport(host, port);
|
||||
s = connecthostport(host, port, scope_id);
|
||||
if(s < 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -392,22 +393,27 @@ miniwget3(const char * host,
|
|||
static void *
|
||||
miniwget2(const char * host,
|
||||
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;
|
||||
|
||||
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.0");
|
||||
#if 1
|
||||
respbuffer = miniwget3(host, port, path, size,
|
||||
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)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Retrying with HTTP/1.1\n");
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -424,7 +430,10 @@ miniwget2(const char * host,
|
|||
* Return values :
|
||||
* 0 - Failure
|
||||
* 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;
|
||||
if(!url)
|
||||
|
@ -440,7 +449,29 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
|
|||
if(*p1 == '[')
|
||||
{
|
||||
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
|
||||
char * scope;
|
||||
scope = 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, '/');
|
||||
if(p2 && p3)
|
||||
{
|
||||
|
@ -490,22 +521,26 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
|
|||
return 1;
|
||||
}
|
||||
|
||||
void * miniwget(const char * url, int * size)
|
||||
void *
|
||||
miniwget(const char * url, int * size, unsigned int scope_id)
|
||||
{
|
||||
unsigned short port;
|
||||
char * path;
|
||||
/* protocol://host:port/chemin */
|
||||
char hostname[MAXHOSTNAMELEN+1];
|
||||
*size = 0;
|
||||
if(!parseURL(url, hostname, &port, &path))
|
||||
if(!parseURL(url, hostname, &port, &path, &scope_id))
|
||||
return NULL;
|
||||
#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
|
||||
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;
|
||||
char * path;
|
||||
|
@ -514,11 +549,12 @@ void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
|
|||
*size = 0;
|
||||
if(addr)
|
||||
addr[0] = '\0';
|
||||
if(!parseURL(url, hostname, &port, &path))
|
||||
if(!parseURL(url, hostname, &port, &path, &scope_id))
|
||||
return NULL;
|
||||
#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
|
||||
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
|
||||
* Author : Thomas Bernard
|
||||
* Copyright (c) 2005 Thomas Bernard
|
||||
* Copyright (c) 2005-2012 Thomas Bernard
|
||||
* This software is subject to the conditions detailed in the
|
||||
* LICENCE file provided in this distribution.
|
||||
* */
|
||||
|
@ -16,11 +16,11 @@ extern "C" {
|
|||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* 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
|
||||
* LICENCE file provided in this distribution.
|
||||
* */
|
||||
|
@ -20,13 +20,13 @@ int main(int argc, char * * argv)
|
|||
int size, writtensize;
|
||||
FILE *f;
|
||||
char addr[64];
|
||||
|
||||
if(argc < 3) {
|
||||
fprintf(stderr, "Usage:\t%s url file\n", argv[0]);
|
||||
fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
/*data = miniwget(argv[1], &size);*/
|
||||
data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr));
|
||||
data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr), 0);
|
||||
if(!data) {
|
||||
fprintf(stderr, "Error fetching %s\n", argv[1]);
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue