Fix for missing broadcast address on Linux Ethernet taps.

This commit is contained in:
Adam Ierymenko 2014-09-04 13:36:25 -04:00
parent 4dbeb97eb9
commit 6df9546742
3 changed files with 37 additions and 2 deletions

View File

@ -196,6 +196,28 @@ InetAddress InetAddress::netmask() const
return r;
}
InetAddress InetAddress::broadcast() const
throw()
{
InetAddress r(*this);
switch(_sa.saddr.sa_family) {
case AF_INET:
r._sa.sin.sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits()));
break;
case AF_INET6: {
unsigned char *bf = (unsigned char *)r._sa.sin6.sin6_addr.s6_addr;
signed int bitsLeft = (signed int)netmaskBits();
for(unsigned int i=0;i<16;++i) {
if (bitsLeft > 0) {
bf[i] |= (unsigned char)((bitsLeft >= 8) ? 0x00 : (0xff >> bitsLeft));
bitsLeft -= 8;
}
}
} break;
}
return r;
}
bool InetAddress::sameNetworkAs(const InetAddress &ipnet) const
throw()
{

View File

@ -217,6 +217,14 @@ public:
InetAddress netmask() const
throw();
/**
* Constructs a broadcast address from a network/netmask address
*
* @return Broadcast address (only IP portion is meaningful)
*/
InetAddress broadcast() const
throw();
/**
* @return True if this is an IPv4 address
*/

View File

@ -224,8 +224,13 @@ bool LinuxEthernetTap::addIP(const InetAddress &ip)
long cpid = (long)vfork();
if (cpid == 0) {
Utils::redirectUnixOutputs("/dev/null",(const char *)0);
::execl("/sbin/ip","/sbin/ip","addr","add",ip.toString().c_str(),"dev",_dev.c_str(),(const char *)0);
::execl("/usr/sbin/ip","/usr/sbin/ip","addr","add",ip.toString().c_str(),"dev",_dev.c_str(),(const char *)0);
if (ip.isV4()) {
::execl("/sbin/ip","/sbin/ip","addr","add",ip.toString().c_str(),"broadcast",ip.broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
::execl("/usr/sbin/ip","/usr/sbin/ip","addr","add",ip.toString().c_str(),"broadcast",ip.broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
} else {
::execl("/sbin/ip","/sbin/ip","addr","add",ip.toString().c_str(),"dev",_dev.c_str(),(const char *)0);
::execl("/usr/sbin/ip","/usr/sbin/ip","addr","add",ip.toString().c_str(),"dev",_dev.c_str(),(const char *)0);
}
::_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;