miniupnpc/miniupnpc.c: simplified function GetUPNPUrls()

This commit is contained in:
Thomas Bernard 2014-11-05 07:09:42 +01:00
parent 55fc3e4c3c
commit edfd211276
2 changed files with 84 additions and 97 deletions

View File

@ -1,6 +1,9 @@
$Id: Changelog.txt,v 1.198 2014/09/11 14:13:31 nanard Exp $ $Id: Changelog.txt,v 1.199 2014/11/05 06:06:37 nanard Exp $
miniUPnP client Changelog. miniUPnP client Changelog.
2014/11/05:
simplified function GetUPNPUrls()
2014/09/11: 2014/09/11:
use remoteHost arg of DeletePortMapping use remoteHost arg of DeletePortMapping

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpc.c,v 1.116 2014/01/31 14:09:03 nanard Exp $ */ /* $Id: miniupnpc.c,v 1.120 2014/11/05 06:06:38 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Web : http://miniupnp.free.fr/ * Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD * Author : Thomas BERNARD
@ -732,27 +732,76 @@ MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist)
} }
} }
static void static char *
url_cpy_or_cat(char * dst, const char * src, int n) build_absolute_url(const char * baseurl, const char * descURL,
const char * url, unsigned int scope_id)
{ {
if( (src[0] == 'h') int l, n;
&&(src[1] == 't') char * s;
&&(src[2] == 't') const char * base;
&&(src[3] == 'p') char * p;
&&(src[4] == ':') #ifdef IF_NAMESIZE
&&(src[5] == '/') char ifname[IF_NAMESIZE];
&&(src[6] == '/')) #else
{ char scope_str[8];
strncpy(dst, src, n); #endif
if( (url[0] == 'h')
&&(url[1] == 't')
&&(url[2] == 't')
&&(url[3] == 'p')
&&(url[4] == ':')
&&(url[5] == '/')
&&(url[6] == '/'))
return strdup(url);
base = (baseurl[0] == '\0') ? descURL : baseurl;
n = strlen(base);
if(n > 7) {
p = strchr(base + 7, '/');
if(p)
n = p - base;
} }
else l = n + strlen(url) + 1;
{ if(url[0] != '/')
int l = strlen(dst); l++;
if(src[0] != '/') if(scope_id != 0) {
dst[l++] = '/'; #ifdef IF_NAMESIZE
if(l<=n) if(if_indextoname(scope_id, ifname)) {
strncpy(dst + l, src, n - l); l += 3 + strlen(ifname); /* 3 == strlen(%25) */
} }
#else
/* under windows, scope is numerical */
l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
#endif
}
s = malloc(l);
if(s == NULL) return NULL;
memcpy(s, base, n);
if(scope_id != 0) {
s[n] = '\0';
if(0 == memcmp(s, "http://[fe80:", 13)) {
/* this is a linklocal IPv6 address */
p = strchr(s, ']');
if(p) {
/* insert %25<scope> into URL */
#ifdef IF_NAMESIZE
memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, ifname, strlen(ifname));
n += 3 + strlen(ifname);
#else
memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, scope_str, strlen(scope_str));
n += 3 + strlen(scope_str);
#endif
}
}
}
if(url[0] != '/')
s[n++] = '/';
memcpy(s + n, url, l - n);
return s;
} }
/* Prepare the Urls for usage... /* Prepare the Urls for usage...
@ -761,89 +810,24 @@ MINIUPNP_LIBSPEC void
GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
const char * descURL, unsigned int scope_id) const char * descURL, unsigned int scope_id)
{ {
char * p;
int n1, n2, n3, n4;
#ifdef IF_NAMESIZE
char ifname[IF_NAMESIZE];
#else
char scope_str[8];
#endif
n1 = strlen(data->urlbase);
if(n1==0)
n1 = strlen(descURL);
if(scope_id != 0) {
#ifdef IF_NAMESIZE
if(if_indextoname(scope_id, ifname)) {
n1 += 3 + strlen(ifname); /* 3 == strlen(%25) */
}
#else
/* under windows, scope is numerical */
snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
#endif
}
n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
n2 = n1; n3 = n1; n4 = n1;
n1 += strlen(data->first.scpdurl);
n2 += strlen(data->first.controlurl);
n3 += strlen(data->CIF.controlurl);
n4 += strlen(data->IPv6FC.controlurl);
/* allocate memory to store URLs */
urls->ipcondescURL = (char *)malloc(n1);
urls->controlURL = (char *)malloc(n2);
urls->controlURL_CIF = (char *)malloc(n3);
urls->controlURL_6FC = (char *)malloc(n4);
/* strdup descURL */ /* strdup descURL */
urls->rootdescURL = strdup(descURL); urls->rootdescURL = strdup(descURL);
/* get description of WANIPConnection */ /* get description of WANIPConnection */
if(data->urlbase[0] != '\0') urls->ipcondescURL = build_absolute_url(data->urlbase, descURL,
strncpy(urls->ipcondescURL, data->urlbase, n1); data->first.scpdurl, scope_id);
else urls->controlURL = build_absolute_url(data->urlbase, descURL,
strncpy(urls->ipcondescURL, descURL, n1); data->first.controlurl, scope_id);
p = strchr(urls->ipcondescURL+7, '/'); urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL,
if(p) p[0] = '\0'; data->CIF.controlurl, scope_id);
if(scope_id != 0) { urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL,
if(0 == memcmp(urls->ipcondescURL, "http://[fe80:", 13)) { data->IPv6FC.controlurl, scope_id);
/* this is a linklocal IPv6 address */
p = strchr(urls->ipcondescURL, ']');
if(p) {
/* insert %25<scope> into URL */
#ifdef IF_NAMESIZE
memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, ifname, strlen(ifname));
#else
memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, scope_str, strlen(scope_str));
#endif
}
}
}
strncpy(urls->controlURL, urls->ipcondescURL, n2);
strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4);
url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2);
url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
url_cpy_or_cat(urls->controlURL_6FC, data->IPv6FC.controlurl, n4);
#ifdef DEBUG #ifdef DEBUG
printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL, printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL);
(unsigned)strlen(urls->ipcondescURL), n1); printf("urls->controlURL='%s'\n", urls->controlURL);
printf("urls->controlURL='%s' %u n2=%d\n", urls->controlURL, printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF);
(unsigned)strlen(urls->controlURL), n2); printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC);
printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
(unsigned)strlen(urls->controlURL_CIF), n3);
printf("urls->controlURL_6FC='%s' %u n4=%d\n", urls->controlURL_6FC,
(unsigned)strlen(urls->controlURL_6FC), n4);
#endif #endif
} }