[SOLVED] Validating IP address based on the netmask
In the settings page of my application, I have fields to set the IP address and the netmask. I validate if those fields are really IP address using regex, however I need to verify also if the given IP address is valid based on given netmask. I am willing to do it with binary operations but I couldn't manage a way to get it right. I convert those fields into quint32 using QHostAddress toIPv4Address, however I couldn't find an way to validate it. I'd appreciate if anyone could shed a light here.
Using this IP and mask as example:
QString ip = "192.168.0.1"; QString mask = "255.255.255.0";
First, you need to convert your IP and mask to binary, like this:
QString binaryIp; foreach (const QString& s, ip.split(".")) binaryIp += QString::number(s.toInt(), 2).rightJustified(8, '0'); QString binaryMask; foreach (const QString& r, mask.split(".")) binaryMask += QString::number(r.toInt(), 2).rightJustified(8, '0');
And then convert the whole number back to decimal:
qint64 decimalIp = binaryIp.toLongLong(NULL, 2); qint64 decimalMask = binaryMask.toLongLong(NULL, 2);
After that, let's proceed to find out what is the network and the broadcast address:
qint64 network = (decimalIp & decimalMask); qint64 temp = (ip | ~mask); QString binaryBroadcast = QString::number(temp, 2).right(32); qint64 broadcast = binaryBroadcast.toLongLong(NULL, 2);
Having both network and broadcast addresses, you can check If any IP is in the subnet range by converting the given IP to decimal and checking if it's greater than network and lower than broadcast:
if (anyDecimalIp >= network && anyDecimalIp <= broadcast) // It is in range else // It is NOT in range
I have fields to set the IP address [...] I validate if those fields are really IP address using regex
Don't do that.
QHostAddress::QHostAddress(const QString & address)will do that for you (
bool isNull() const).
I need to verify also if the given IP address is valid based on given netmask
bool QHostAddress::isInSubnet(const QHostAddress & subnet, int netmask) constdoes what you want.
Btw.: Please don't use special input fields for IPv4 addresses. It's 2015 and all operating systems have IPv6 support. Limiting an application to IPv4 only because of bad GUI design is really stupid.