diff options
Diffstat (limited to 'external/miniupnpc/miniupnpc.c')
-rw-r--r-- | external/miniupnpc/miniupnpc.c | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/external/miniupnpc/miniupnpc.c b/external/miniupnpc/miniupnpc.c index fc665a0a4..5eb9500e3 100644 --- a/external/miniupnpc/miniupnpc.c +++ b/external/miniupnpc/miniupnpc.c @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.c,v 1.135 2015/07/23 20:40:08 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab */ -/* Project : miniupnp +/* $Id: miniupnpc.c,v 1.148 2016/01/24 17:24:36 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp * Web : http://miniupnp.free.fr/ * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard + * copyright (c) 2005-2016 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #include <stdlib.h> @@ -72,6 +72,25 @@ #define SERVICEPREFIX "u" #define SERVICEPREFIX2 'u' +/* check if an ip address is a private (LAN) address + * see https://tools.ietf.org/html/rfc1918 */ +static int is_rfc1918addr(const char * addr) +{ + /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ + if(COMPARE(addr, "192.168.")) + return 1; + /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ + if(COMPARE(addr, "10.")) + return 1; + /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ + if(COMPARE(addr, "172.")) { + int i = atoi(addr + 4); + if((16 <= i) && (i <= 31)) + return 1; + } + return 0; +} + /* root description parsing */ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) { @@ -107,6 +126,7 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service, int soapbodylen; char * buf; int n; + int status_code; *bufsize = 0; snprintf(soapact, sizeof(soapact), "%s#%s", service, action); @@ -210,11 +230,15 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service, return NULL; } - buf = getHTTPResponse(s, bufsize); + buf = getHTTPResponse(s, bufsize, &status_code); #ifdef DEBUG if(*bufsize > 0 && buf) { - printf("SOAP Response :\n%.*s\n", *bufsize, buf); + printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf); + } + else + { + printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize); } #endif closesocket(s); @@ -526,7 +550,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) * 3 = an UPnP device has been found but was not recognized as an IGD * * In any positive non zero return case, the urls and data structures - * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to + * passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to * free allocated memory. */ MINIUPNP_LIBSPEC int @@ -547,6 +571,8 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, int n_igd = 0; char extIpAddr[16]; char myLanAddr[40]; + int status_code = -1; + if(!devlist) { #ifdef DEBUG @@ -570,7 +596,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), myLanAddr, sizeof(myLanAddr), - dev->scope_id); + dev->scope_id, &status_code); #ifdef DEBUG if(!desc[i].xml) { @@ -604,20 +630,25 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, parserootdesc(desc[i].xml, desc[i].size, data); if(desc[i].is_igd || state >= 3 ) { + int is_connected; + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); /* in state 2 and 3 we dont test if device is connected ! */ if(state >= 2) goto free_and_return; + is_connected = UPNPIGD_IsConnected(urls, data); #ifdef DEBUG printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, - UPNPIGD_IsConnected(urls, data)); + urls->controlURL, is_connected); #endif /* checks that status is connected AND there is a external IP address assigned */ - if(UPNPIGD_IsConnected(urls, data) - && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) - goto free_and_return; + if(is_connected && + (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { + if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') + && (0 != strcmp(extIpAddr, "0.0.0.0"))) + goto free_and_return; + } FreeUPNPUrls(urls); if(data->second.servicetype[0] != '\0') { #ifdef DEBUG @@ -629,14 +660,17 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); + is_connected = UPNPIGD_IsConnected(urls, data); #ifdef DEBUG printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, - UPNPIGD_IsConnected(urls, data)); + urls->controlURL, is_connected); #endif - if(UPNPIGD_IsConnected(urls, data) - && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) - goto free_and_return; + if(is_connected && + (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { + if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') + && (0 != strcmp(extIpAddr, "0.0.0.0"))) + goto free_and_return; + } FreeUPNPUrls(urls); } } @@ -670,8 +704,9 @@ UPNP_GetIGDFromUrl(const char * rootdescurl, { char * descXML; int descXMLsize = 0; + descXML = miniwget_getaddr(rootdescurl, &descXMLsize, - lanaddr, lanaddrlen, 0); + lanaddr, lanaddrlen, 0, NULL); if(descXML) { memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); |