158 if ((a & 0xff000000U) == 0x7f000000U)
159 return LoopbackAddress;
160 if ((a & 0xf0000000U) == 0xe0000000U)
161 return MulticastAddress;
162 if ((a & 0xffff0000U) == 0xa9fe0000U)
163 return LinkLocalAddress;
164 if ((a & 0xff000000U) == 0)
165 return LocalNetAddress;
166 if ((a & 0xf0000000U) == 0xf0000000U) {
167 if (a == 0xffffffffU)
168 return BroadcastAddress;
169 return UnknownAddress;
171 if (((a & 0xff000000U) == 0x0a000000U)
172 || ((a & 0xfff00000U) == 0xac100000U)
173 || ((a & 0xffff0000U) == 0xc0a80000U))
174 return PrivateNetworkAddress;
178 return GlobalAddress;
184 quint32 high16 = qFromBigEndian(a6_32.c[0]) >> 16;
185 switch (high16 >> 8) {
187 return MulticastAddress;
189 switch (high16 & 0xffc0) {
191 return SiteLocalAddress;
194 return LinkLocalAddress;
197 return UnknownAddress;
201 return UniqueLocalAddress;
203 return GlobalAddress;
207 quint64 low64 = qFromBigEndian(a6_64.c[1]);
209 return LoopbackAddress;
210 if (low64 >> 32 == 0xffff) {
211 Q_ASSERT(quint32(low64) == 0);
212 return LocalNetAddress;
215 return GlobalAddress;
217 if (protocol == QHostAddress::UnknownNetworkLayerProtocol)
218 return UnknownAddress;
221 return LocalNetAddress;
226 static const quint8 zeroes[16] = { 0 };
237 if (address.protocol() == QHostAddress::IPv4Protocol) {
238 ip.v4 = qToBigEndian(address.toIPv4Address());
240 }
else if (address.protocol() == QHostAddress::IPv6Protocol) {
241 memcpy(ip.v6, address.toIPv6Address().c, 16);
285 if (ptr < end && memcmp(ptr + 1, zeroes, end - ptr - 1) != 0)
294 Q_ASSERT(end == 32 || end == 128);
299 quint8 bytemask = 256 - (1 << (8 - (start & 7)));
300 where[start / 8] &= bytemask;
303 memset(where + (start + 7) / 8, 0, end / 8 - (start + 7) / 8);
308 if (length == 255 || protocol == QHostAddress::AnyIPProtocol ||
309 protocol == QHostAddress::UnknownNetworkLayerProtocol) {
310 return QHostAddress();
311 }
else if (protocol == QHostAddress::IPv4Protocol) {
315 else if (length == 32)
316 a = quint32(0xffffffff);
318 a = quint32(0xffffffff) >> (32 - length) << (32 - length);
319 return QHostAddress(a);
322 memset(a6.c, 0xFF,
sizeof(a6));
323 clearBits(a6.c, length, 128);
324 return QHostAddress(a6);
665quint32 QHostAddress::toIPv4Address(
bool *ok)
const
669 *ok = d->protocol == QHostAddress::IPv4Protocol || d->protocol == QHostAddress::AnyIPProtocol
670 || (d->protocol == QHostAddress::IPv6Protocol
671 && convertToIpv4(dummy, d->a6, ConversionMode(QHostAddress::ConvertV4MappedToIPv4
672 | QHostAddress::ConvertUnspecifiedAddress)));
713QString QHostAddress::toString()
const
716 if (d->protocol == QHostAddress::IPv4Protocol
717 || d->protocol == QHostAddress::AnyIPProtocol) {
718 quint32 i = toIPv4Address();
719 QIPAddressUtils::toString(s, i);
720 }
else if (d->protocol == QHostAddress::IPv6Protocol) {
721 QIPAddressUtils::toString(s, d->a6.c);
722 if (!d->scopeId.isEmpty())
723 s += u'%' + d->scopeId;
811bool QHostAddress::isEqual(
const QHostAddress &other, ConversionMode mode)
const
816 if (d->protocol == QHostAddress::IPv4Protocol) {
817 switch (other.d->protocol) {
818 case QHostAddress::IPv4Protocol:
819 return d->a == other.d->a;
820 case QHostAddress::IPv6Protocol:
822 return convertToIpv4(a4, other.d->a6, mode) && (a4 == d->a);
823 case QHostAddress::AnyIPProtocol:
824 return (mode & QHostAddress::ConvertUnspecifiedAddress) && d->a == 0;
825 case QHostAddress::UnknownNetworkLayerProtocol:
830 if (d->protocol == QHostAddress::IPv6Protocol) {
831 switch (other.d->protocol) {
832 case QHostAddress::IPv4Protocol:
834 return convertToIpv4(a4, d->a6, mode) && (a4 == other.d->a);
835 case QHostAddress::IPv6Protocol:
836 return memcmp(&d->a6, &other.d->a6,
sizeof(Q_IPV6ADDR)) == 0;
837 case QHostAddress::AnyIPProtocol:
838 return (mode & QHostAddress::ConvertUnspecifiedAddress)
839 && (d->a6_64.c[0] == 0) && (d->a6_64.c[1] == 0);
840 case QHostAddress::UnknownNetworkLayerProtocol:
845 if ((d->protocol == QHostAddress::AnyIPProtocol)
846 && (mode & QHostAddress::ConvertUnspecifiedAddress)) {
847 switch (other.d->protocol) {
848 case QHostAddress::IPv4Protocol:
849 return other.d->a == 0;
850 case QHostAddress::IPv6Protocol:
851 return (other.d->a6_64.c[0] == 0) && (other.d->a6_64.c[1] == 0);
857 return d->protocol == other.d->protocol;
864bool QHostAddress::operator ==(SpecialAddress other)
const
866 quint32 ip4 = INADDR_ANY;
869 return d->protocol == QHostAddress::UnknownNetworkLayerProtocol;
872 ip4 = INADDR_BROADCAST;
876 ip4 = INADDR_LOOPBACK;
880 return d->protocol == QHostAddress::AnyIPProtocol;
887 if (d->protocol == QHostAddress::IPv6Protocol) {
888 quint64 second = quint8(other == LocalHostIPv6);
889 return d->a6_64.c[0] == 0 && d->a6_64.c[1] == qToBigEndian(second);
895 return d->protocol == QHostAddress::IPv4Protocol && d->a == ip4;
933bool QHostAddress::isInSubnet(
const QHostAddress &subnet,
int netmask)
const
935 if (subnet.protocol() != d->protocol || netmask < 0)
944 if (d->protocol == QHostAddress::IPv4Protocol) {
947 ip4.ip = qToBigEndian(d->a);
948 net4.ip = qToBigEndian(subnet.d->a);
951 }
else if (d->protocol == QHostAddress::IPv6Protocol) {
955 net = subnet.d->a6.c;
960 if (netmask >= 8 && memcmp(ip, net, netmask / 8) != 0)
962 if ((netmask & 7) == 0)
966 quint8 bytemask = 256 - (1 << (8 - (netmask & 7)));
967 quint8 ipbyte = ip[netmask / 8];
968 quint8 netbyte = net[netmask / 8];
969 return (ipbyte & bytemask) == (netbyte & bytemask);
1011std::pair<QHostAddress,
int> QHostAddress::parseSubnet(
const QString &subnet)
1028 const std::pair<QHostAddress,
int> invalid = std::pair(QHostAddress(), -1);
1029 if (subnet.isEmpty())
1032 qsizetype slash = subnet.indexOf(u'/');
1033 QStringView netStr(subnet);
1035 netStr.truncate(slash);
1038 bool isIpv6 = netStr.contains(u':');
1042 if (!isIpv6 && subnet.indexOf(u'.', slash + 1) != -1) {
1046 if (!mask.setAddress(subnet.mid(slash + 1)))
1048 if (!parser.setAddress(mask))
1050 netmask = parser.prefixLength();
1053 netmask = QStringView{subnet}.mid(slash + 1).toUInt(&ok);
1067 if (!net.setAddress(netStr.toString()))
1070 clearBits(net.d->a6.c, netmask, 128);
1071 return std::pair(net, netmask);
1078 auto parts = netStr.split(u'.');
1079 if (parts.isEmpty() || parts.size() > 4)
1082 if (parts.constLast().isEmpty())
1086 for (
int i = 0; i < parts.size(); ++i) {
1088 uint byteValue = parts.at(i).toUInt(&ok);
1089 if (!ok || byteValue > 255)
1095 addr <<= 8 * (4 - parts.size());
1096 if (netmask == -1) {
1097 netmask = 8 * parts.size();
1098 }
else if (netmask == 0) {
1103 }
else if (netmask != 32) {
1105 quint32 mask = quint32(0xffffffff) >> (32 - netmask) << (32 - netmask);
1109 return std::pair(QHostAddress(addr), netmask);