miniupnpd: autodetect LAN interface netmask instead of defaulting to /24

Fix #23
This commit is contained in:
Thomas Bernard 2013-03-23 11:50:57 +01:00
parent 2b2efd4459
commit 961e1c35d3
9 changed files with 58 additions and 33 deletions

View File

@ -1,4 +1,7 @@
$Id: Changelog.txt,v 1.331 2013/02/11 10:37:06 nanard Exp $
$Id: Changelog.txt,v 1.332 2013/03/23 10:46:53 nanard Exp $
2013/03/23:
autodetect LAN interface netmask instead of defaulting to /24
2013/02/11:
Use $(DESTDIR) in Makefile.linux.

View File

@ -1,7 +1,7 @@
/* $Id: getconnstatus.c,v 1.4 2011/05/23 20:22:41 nanard Exp $ */
/* $Id: getconnstatus.c,v 1.6 2013/03/23 10:46:54 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2011 Thomas Bernard
* (c) 2011-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -35,7 +35,7 @@ get_wan_connection_status(const char * ifname)
/* we need a better implementation here.
* I'm afraid it should be device specific */
r = getifaddr(ifname, addr, INET_ADDRSTRLEN);
r = getifaddr(ifname, addr, INET_ADDRSTRLEN, NULL, NULL);
return (r < 0) ? STATUS_DISCONNECTED : STATUS_CONNECTED;
}

View File

@ -1,7 +1,7 @@
/* $Id: getifaddr.c,v 1.14 2012/02/07 11:05:07 nanard Exp $ */
/* $Id: getifaddr.c,v 1.16 2013/03/23 10:46:54 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2011 Thomas Bernard
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -26,7 +26,8 @@
#endif
int
getifaddr(const char * ifname, char * buf, int len)
getifaddr(const char * ifname, char * buf, int len,
struct in_addr * addr, struct in_addr * mask)
{
#ifndef USE_GETIFADDRS
/* use ioctl SIOCGIFADDR. Works only for ip v4 */
@ -34,7 +35,7 @@ getifaddr(const char * ifname, char * buf, int len)
int s;
struct ifreq ifr;
int ifrlen;
struct sockaddr_in * addr;
struct sockaddr_in * ifaddr;
ifrlen = sizeof(ifr);
if(!ifname || ifname[0]=='\0')
@ -52,13 +53,25 @@ getifaddr(const char * ifname, char * buf, int len)
close(s);
return -1;
}
addr = (struct sockaddr_in *)&ifr.ifr_addr;
if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len))
ifaddr = (struct sockaddr_in *)&ifr.ifr_addr;
if(addr) *addr = ifaddr->sin_addr;
if(!inet_ntop(AF_INET, &ifaddr->sin_addr, buf, len))
{
syslog(LOG_ERR, "inet_ntop(): %m");
close(s);
return -1;
}
if(mask)
{
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if(ioctl(s, SIOCGIFNETMASK, &ifr, &ifrlen) < 0)
{
syslog(LOG_ERR, "ioctl(s, SIOCGIFNETMASK, ...): %m");
close(s);
return -1;
}
*mask = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr;
}
close(s);
#else /* ifndef USE_GETIFADDRS */
/* Works for all address families (both ip v4 and ip v6) */
@ -85,6 +98,8 @@ getifaddr(const char * ifname, char * buf, int len)
inet_ntop(ife->ifa_addr->sa_family,
&((struct sockaddr_in *)ife->ifa_addr)->sin_addr,
buf, len);
if(addr) *addr = ((struct sockaddr_in *)ife->ifa_addr)->sin_addr;
if(mask) *mask = ((struct sockaddr_in *)ife->ifa_netmask)->sin_addr;
break;
/*
case AF_INET6:

View File

@ -1,19 +1,22 @@
/* $Id: getifaddr.h,v 1.5 2011/05/15 08:59:27 nanard Exp $ */
/* $Id: getifaddr.h,v 1.8 2013/03/23 10:46:54 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2011 Thomas Bernard
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef GETIFADDR_H_INCLUDED
#define GETIFADDR_H_INCLUDED
struct in_addr;
/* getifaddr()
* take a network interface name and write the
* ip v4 address as text in the buffer
* returns: 0 success, -1 failure */
int
getifaddr(const char * ifname, char * buf, int len);
getifaddr(const char * ifname, char * buf, int len,
struct in_addr * addr, struct in_addr * mask);
/* find a non link local IP v6 address for the interface.
* if ifname is NULL, look for all interfaces */

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpd.c,v 1.173 2013/02/06 10:50:04 nanard Exp $ */
/* $Id: miniupnpd.c,v 1.174 2013/03/23 10:46:54 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2013 Thomas Bernard
@ -561,7 +561,8 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str)
/* not starting with a digit : suppose it is an interface name */
memcpy(lan_addr->ifname, str, n);
lan_addr->ifname[n] = '\0';
if(getifaddr(lan_addr->ifname, lan_addr->str, sizeof(lan_addr->str)) < 0)
if(getifaddr(lan_addr->ifname, lan_addr->str, sizeof(lan_addr->str),
&lan_addr->addr, &lan_addr->mask) < 0)
goto parselan_error;
}
else
@ -570,9 +571,9 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str)
goto parselan_error;
memcpy(lan_addr->str, str, n);
lan_addr->str[n] = '\0';
if(!inet_aton(lan_addr->str, &lan_addr->addr))
goto parselan_error;
}
if(!inet_aton(lan_addr->str, &lan_addr->addr))
goto parselan_error;
if(*p == '/')
{
const char * q = ++p;
@ -598,7 +599,7 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str)
lan_addr->mask.s_addr = htonl(nbits ? (0xffffffffu << (32 - nbits)) : 0);
}
}
else
else if(lan_addr->mask.s_addr == 0)
{
/* by default, networks are /24 */
lan_addr->mask.s_addr = htonl(0xffffff00u);

View File

@ -1,6 +1,6 @@
/* $Id: natpmp.c,v 1.32 2012/05/27 22:36:03 nanard Exp $ */
/* $Id: natpmp.c,v 1.33 2013/03/23 10:46:55 nanard Exp $ */
/* MiniUPnP project
* (c) 2007-2012 Thomas Bernard
* (c) 2007-2013 Thomas Bernard
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -96,7 +96,7 @@ 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) < 0) {
} else if(getifaddr(ext_if_name, tmp, INET_ADDRSTRLEN, NULL, 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) */

View File

@ -1,11 +1,12 @@
/* $Id: testgetifaddr.c,v 1.4 2012/03/05 20:36:17 nanard Exp $ */
/* $Id: testgetifaddr.c,v 1.6 2013/03/23 10:46:55 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2011 Thomas Bernard
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <stdio.h>
#include <syslog.h>
#include <netinet/in.h>
#include "getifaddr.h"
#if defined(__sun)
@ -14,17 +15,19 @@
#endif
int main(int argc, char * * argv) {
char addr[64];
char str_addr[64];
struct in_addr addr;
struct in_addr mask;
if(argc < 2) {
fprintf(stderr, "Usage:\t%s interface_name\n", argv[0]);
return 1;
}
openlog("testgetifaddr", LOG_CONS|LOG_PERROR, LOG_USER);
if(getifaddr(argv[1], addr, sizeof(addr)) < 0) {
if(getifaddr(argv[1], str_addr, sizeof(str_addr), &addr, &mask) < 0) {
fprintf(stderr, "Cannot get address for interface %s.\n", argv[1]);
return 1;
}
printf("Interface %s has IP address %s.\n", argv[1], addr);
printf("Interface %s has IP address %s.\n", argv[1], str_addr);
return 0;
}

View File

@ -1,7 +1,7 @@
/* $Id: upnpdescgen.c,v 1.71 2012/10/04 22:08:08 nanard Exp $ */
/* $Id: upnpdescgen.c,v 1.72 2013/03/23 10:46:55 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -1198,7 +1198,7 @@ genEventVars(int * len, const struct serviceDesc * s, const char * servns)
str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
else {
char ext_ip_addr[INET_ADDRSTRLEN];
if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN) < 0) {
if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
str = strcat_str(str, len, &tmplen, "0.0.0.0");
} else {
str = strcat_str(str, len, &tmplen, ext_ip_addr);

View File

@ -1,7 +1,7 @@
/* $Id: upnpsoap.c,v 1.114 2013/02/06 12:40:25 nanard Exp $ */
/* $Id: upnpsoap.c,v 1.115 2013/03/23 10:46:56 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
@ -191,7 +191,7 @@ GetCommonLinkProperties(struct upnphttp * h, const char * action)
if(upstream_bitrate == 0) upstream_bitrate = data.baudrate;
}
}
if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN) < 0) {
if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
status = "Down";
}
bodylen = snprintf(body, sizeof(body), resp,
@ -269,7 +269,7 @@ GetExternalIPAddress(struct upnphttp * h, const char * action)
{
strncpy(ext_ip_addr, use_ext_ip_addr, INET_ADDRSTRLEN);
}
else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN) < 0)
else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0)
{
syslog(LOG_ERR, "Failed to get ip address for interface %s",
ext_if_name);