diff --git a/miniupnpd/miniupnpd.c b/miniupnpd/miniupnpd.c index 74911a6..b11bc7e 100644 --- a/miniupnpd/miniupnpd.c +++ b/miniupnpd/miniupnpd.c @@ -990,6 +990,12 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str) if(!inet_aton(lan_addr->ext_ip_str, &lan_addr->ext_ip_addr)) { /* error */ fprintf(stderr, "Error parsing address : %s\n", lan_addr->ext_ip_str); + return -1; + } + if(addr_is_reserved(&lan_addr->ext_ip_addr)) { + /* error */ + fprintf(stderr, "Error: option ext_ip address contains reserved / private address : %s\n", lan_addr->ext_ip_str); + return -1; } } } @@ -1070,6 +1076,7 @@ init(int argc, char * * argv, struct runtime_vars * v) int pid; int debug_flag = 0; int openlog_option; + struct in_addr addr; struct sigaction sa; /*const char * logfilename = 0;*/ const char * presurl = 0; @@ -1606,6 +1613,17 @@ init(int argc, char * * argv, struct runtime_vars * v) goto print_usage; } + if (use_ext_ip_addr) { + if (inet_pton(AF_INET, use_ext_ip_addr, &addr) != 1) { + fprintf(stderr, "Error: option ext_ip contains invalid address %s\n", use_ext_ip_addr); + return 1; + } + if (addr_is_reserved(&addr)) { + fprintf(stderr, "Error: option ext_ip contains reserved / private address %s, not public routable\n", use_ext_ip_addr); + return 1; + } + } + if(debug_flag) { pid = getpid(); diff --git a/miniupnpd/natpmp.c b/miniupnpd/natpmp.c index 0ed09e0..8648dfb 100644 --- a/miniupnpd/natpmp.c +++ b/miniupnpd/natpmp.c @@ -94,6 +94,7 @@ error: static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr) { #ifndef MULTIPLE_EXTERNAL_IP + struct in_addr addr; char tmp[16]; UNUSED(senderaddr); @@ -103,10 +104,13 @@ static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr if(!ext_if_name || ext_if_name[0]=='\0') { resp[3] = 3; /* Network Failure (e.g. NAT box itself * has not obtained a DHCP lease) */ - } else if(getifaddr(ext_if_name, tmp, INET_ADDRSTRLEN, NULL, NULL) < 0) { + } else if(getifaddr(ext_if_name, tmp, INET_ADDRSTRLEN, &addr, NULL) < 0) { syslog(LOG_ERR, "Failed to get IP for interface %s", ext_if_name); resp[3] = 3; /* Network Failure (e.g. NAT box itself * has not obtained a DHCP lease) */ + } else if (addr_is_reserved(&addr)) { + resp[3] = 3; /* Network Failure, box has not obtained + public IP address */ } else { inet_pton(AF_INET, tmp, resp+8); /* ok */ } diff --git a/miniupnpd/upnpdescgen.c b/miniupnpd/upnpdescgen.c index 88e00c1..b2583eb 100644 --- a/miniupnpd/upnpdescgen.c +++ b/miniupnpd/upnpdescgen.c @@ -1281,8 +1281,9 @@ genEventVars(int * len, const struct serviceDesc * s) if(use_ext_ip_addr) str = strcat_str(str, len, &tmplen, use_ext_ip_addr); else { + struct in_addr addr; char ext_ip_addr[INET_ADDRSTRLEN]; - if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) { + if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, &addr, NULL) < 0 || addr_is_reserved(&addr)) { str = strcat_str(str, len, &tmplen, "0.0.0.0"); } else { str = strcat_str(str, len, &tmplen, ext_ip_addr); diff --git a/miniupnpd/upnpsoap.c b/miniupnpd/upnpsoap.c index b4f156c..5a3eafc 100644 --- a/miniupnpd/upnpsoap.c +++ b/miniupnpd/upnpsoap.c @@ -332,17 +332,20 @@ GetExternalIPAddress(struct upnphttp * h, const char * action, const char * ns) * There is usually no NAT with IPv6 */ #ifndef MULTIPLE_EXTERNAL_IP + struct in_addr addr; if(use_ext_ip_addr) { strncpy(ext_ip_addr, use_ext_ip_addr, INET_ADDRSTRLEN); ext_ip_addr[INET_ADDRSTRLEN - 1] = '\0'; } - else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) + else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, &addr, NULL) < 0) { syslog(LOG_ERR, "Failed to get ip address for interface %s", ext_if_name); strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN); } + if (addr_is_reserved(&addr)) + strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN); #else struct lan_addr_s * lan_addr; strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);