extract the scope from the socket address (sockaddr pointer)

obviously something which was not done before by QHostAddress itself, it is
now tho

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-03-30 02:20:01 +02:00
parent 25beb62343
commit 64a1e01cac
4 changed files with 48 additions and 54 deletions

View file

@ -32,6 +32,10 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#ifndef QT_NO_IPV6IFNAME
# include <net/if.h>
#endif
QT_BEGIN_NAMESPACE
static const char addrscopeseparator = '%';
@ -250,6 +254,7 @@ bool QHostAddress::setAddress(const QByteArray &address)
d->scopeId.clear();
return true;
}
clear();
return false;
}
@ -263,24 +268,47 @@ bool QHostAddress::setAddress(const QByteArray &address)
*/
void QHostAddress::setAddress(const struct sockaddr *sockaddr)
{
clear();
if (!sockaddr) {
clear();
return;
}
if (sockaddr->sa_family == AF_INET) {
QSTACKARRAY(char, ntopbuffer, INET_ADDRSTRLEN + 1);
if (inet_ntop(AF_INET, &((sockaddr_in *)sockaddr)->sin_addr, ntopbuffer, INET_ADDRSTRLEN) != NULL) {
d->protocol = QAbstractSocket::IPv4Protocol;
d->ipString = ntopbuffer;
d->scopeId.clear();
} else {
clear();
}
return;
}
#ifndef QT_NO_IPV6
if (sockaddr->sa_family == AF_INET6) {
QSTACKARRAY(char, ntopbuffer, INET6_ADDRSTRLEN + 1);
if (inet_ntop(AF_INET6, &((sockaddr_in6 *)sockaddr)->sin6_addr, ntopbuffer, INET6_ADDRSTRLEN) != NULL) {
const sockaddr_in6* si6 = (sockaddr_in6 *)sockaddr;
if (inet_ntop(AF_INET6, &(si6->sin6_addr), ntopbuffer, INET6_ADDRSTRLEN) != NULL) {
d->protocol = QAbstractSocket::IPv6Protocol;
d->ipString = ntopbuffer;
d->scopeId.clear();
if (si6->sin6_scope_id) {
#ifndef QT_NO_IPV6IFNAME
QSTACKARRAY(char, indexofnamebuffer, IFNAMSIZ);
if (::if_indextoname(si6->sin6_scope_id, indexofnamebuffer)) {
d->scopeId = indexofnamebuffer;
}
#endif
if (d->scopeId.isEmpty()) {
d->scopeId = QByteArray::number(si6->sin6_scope_id);
}
}
} else {
clear();
}
return;
}
#endif
clear();
}
/*!

View file

@ -195,10 +195,7 @@ QHostInfo QHostInfoPrivate::fromName(const QString &hostName)
}
#ifndef QT_NO_IPV6
else if (node->ai_family == AF_INET6) {
sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr;
QHostAddress addr(node->ai_addr);
if (sa6->sin6_scope_id)
addr.setScopeId(QByteArray::number(sa6->sin6_scope_id));
if (!addresses.contains(addr))
addresses.append(addr);
}

View file

@ -56,34 +56,6 @@ static QString makeHwAddress(const uchar *data)
return QString::fromLatin1(snprintfbuf, sizeof(snprintfbuf) - 1);
}
static QHostAddress addressFromSockaddr(sockaddr *sa)
{
QHostAddress address;
if (!sa)
return address;
if (sa->sa_family == AF_INET)
address.setAddress(sa);
#ifndef QT_NO_IPV6
else if (sa->sa_family == AF_INET6) {
address.setAddress(sa);
int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
if (scope) {
#ifndef QT_NO_IPV6IFNAME
QSTACKARRAY(char, scopeid, IFNAMSIZ);
if (::if_indextoname(scope, scopeid) != 0) {
address.setScopeId(QByteArray(scopeid));
} else
#endif
address.setScopeId(QByteArray::number(scope));
}
}
#endif
return address;
}
QList<QNetworkInterfacePrivate *> QNetworkInterfacePrivate::scan()
{
QList<QNetworkInterfacePrivate *> interfaces;
@ -133,15 +105,15 @@ QList<QNetworkInterfacePrivate *> QNetworkInterfacePrivate::scan()
}
QNetworkAddressEntry entry;
entry.d->address = addressFromSockaddr(ifiter->ifa_addr);
entry.d->address = QHostAddress(ifiter->ifa_addr);
if (entry.ip().isNull()) {
// could not parse the address
continue;
}
entry.d->netmask = addressFromSockaddr(ifiter->ifa_netmask);
entry.d->netmask = QHostAddress(ifiter->ifa_netmask);
if (iface->flags & QNetworkInterface::CanBroadcast) {
entry.d->broadcast = addressFromSockaddr(ifiter->ifa_broadaddr);
entry.d->broadcast = QHostAddress(ifiter->ifa_broadaddr);
}
iface->addressEntries << entry;

View file

@ -39,7 +39,7 @@
#include <arpa/inet.h>
#ifndef QT_NO_IPV6IFNAME
#include <net/if.h>
# include <net/if.h>
#endif
#ifdef Q_OS_SOLARIS
@ -59,13 +59,6 @@ static inline void qt_socket_getPortAndAddress(const struct sockaddr_storage *ss
const struct sockaddr_in6 *si6 = (const struct sockaddr_in6 *)ss;
if (addr) {
addr->setAddress((const struct sockaddr *) ss);
#ifndef QT_NO_IPV6IFNAME
QSTACKARRAY(char, scopeid, IFNAMSIZ);
if (::if_indextoname(si6->sin6_scope_id, scopeid)) {
addr->setScopeId(QByteArray(scopeid));
} else
#endif
addr->setScopeId(QByteArray::number(si6->sin6_scope_id));
}
if (port)
*port = ntohs(si6->sin6_port);
@ -296,12 +289,13 @@ bool QAbstractSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint
sockAddrIPv6.sin6_family = AF_INET6;
sockAddrIPv6.sin6_port = htons(port);
QString scopeid = addr.scopeId();
const QByteArray scopeid = addr.scopeId();
bool ok = false;
sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
#ifndef QT_NO_IPV6IFNAME
if (!ok)
sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
if (!ok) {
sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData());
}
#endif
struct in6_addr inAddrIPv6;
inet_pton(AF_INET6, addrStr.constData(), &inAddrIPv6);
@ -406,10 +400,12 @@ bool QAbstractSocketEnginePrivate::nativeBind(const QHostAddress &address, quint
memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
sockAddrIPv6.sin6_family = AF_INET6;
sockAddrIPv6.sin6_port = htons(port);
bool ok = false;
sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
#ifndef QT_NO_IPV6IFNAME
sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData());
#else
sockAddrIPv6.sin6_scope_id = scopeid.toInt();
if (!ok) {
sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData());
}
#endif
struct in6_addr inAddrIPv6;
inet_pton(AF_INET6, addrStr.constData(), &inAddrIPv6);
@ -803,12 +799,13 @@ qint64 QAbstractSocketEnginePrivate::nativeSendDatagram(const char *data, qint64
struct in6_addr ia6;
inet_pton(AF_INET6, hostStr.constData(), &ia6);
sockAddrIPv6.sin6_addr = ia6;
QString scopeid = host.scopeId();
bool ok;
const QByteArray scopeid = host.scopeId();
bool ok = false;
sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
#ifndef QT_NO_IPV6IFNAME
if (!ok)
sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
if (!ok) {
sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData());
}
#endif
sockAddrSize = sizeof(sockAddrIPv6);
sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;