File indexing completed on 2025-01-05 04:37:19
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "address.h" 0008 #include <sys/socket.h> 0009 #include <util/log.h> 0010 0011 using namespace bt; 0012 0013 namespace net 0014 { 0015 Address::Address() 0016 : port_number(0) 0017 { 0018 } 0019 0020 Address::Address(quint32 ip4Addr, Uint16 port) 0021 : QHostAddress(ip4Addr) 0022 , port_number(port) 0023 { 0024 } 0025 0026 Address::Address(quint8 *ip6Addr, Uint16 port) 0027 : QHostAddress(ip6Addr) 0028 , port_number(port) 0029 { 0030 } 0031 0032 Address::Address(const Q_IPV6ADDR &ip6Addr, Uint16 port) 0033 : QHostAddress(ip6Addr) 0034 , port_number(port) 0035 { 0036 } 0037 0038 Address::Address(const struct sockaddr_storage *ss) 0039 : port_number(0) 0040 { 0041 if (ss->ss_family == AF_INET) { 0042 setAddress((const struct sockaddr *)ss); 0043 port_number = ntohs(((const struct sockaddr_in *)ss)->sin_port); 0044 } else if (ss->ss_family == AF_INET6) { 0045 setAddress((const struct sockaddr *)ss); 0046 port_number = ntohs(((const struct sockaddr_in6 *)ss)->sin6_port); 0047 if (isIPv4Mapped()) { 0048 Q_IPV6ADDR ipv6 = toIPv6Address(); 0049 quint32 ip = ipv6[12] << 24 | ipv6[13] << 16 | ipv6[14] << 8 | ipv6[15]; 0050 setAddress(ip); 0051 } 0052 } else 0053 Out(SYS_GEN | LOG_DEBUG) << "Unknown address family" << endl; 0054 } 0055 0056 Address::Address(const QString &host, Uint16 port) 0057 : QHostAddress(host) 0058 , port_number(port) 0059 { 0060 } 0061 0062 Address::Address(const Address &addr) 0063 : QHostAddress(addr) 0064 , port_number(addr.port_number) 0065 { 0066 } 0067 0068 Address::Address(const QHostAddress &addr, Uint16 port) 0069 : QHostAddress(addr) 0070 , port_number(port) 0071 { 0072 } 0073 0074 Address::~Address() 0075 { 0076 } 0077 0078 void Address::toSocketAddress(sockaddr_storage *ss, int &length) const 0079 { 0080 if (protocol() == QAbstractSocket::IPv4Protocol) { 0081 struct sockaddr_in *addr = (struct sockaddr_in *)ss; 0082 memset(addr, 0, sizeof(struct sockaddr_in)); 0083 addr->sin_family = AF_INET; 0084 addr->sin_port = htons(port_number); 0085 addr->sin_addr.s_addr = htonl(toIPv4Address()); 0086 length = sizeof(struct sockaddr_in); 0087 } else { 0088 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ss; 0089 memset(addr, 0, sizeof(struct sockaddr_in6)); 0090 addr->sin6_family = AF_INET6; 0091 addr->sin6_port = htons(port_number); 0092 memcpy(&addr->sin6_addr, toIPv6Address().c, 16); 0093 length = sizeof(struct sockaddr_in6); 0094 } 0095 } 0096 0097 bool Address::operator==(const net::Address &other) const 0098 { 0099 return QHostAddress::operator==(other) && port_number == other.port(); 0100 } 0101 0102 bool Address::operator<(const net::Address &other) const 0103 { 0104 if (ipVersion() != other.ipVersion()) { 0105 return ipVersion() < other.ipVersion(); 0106 } else if (other.ipVersion() == 4) { 0107 return toIPv4Address() == other.toIPv4Address() ? port_number < other.port_number : toIPv4Address() < other.toIPv4Address(); 0108 } else { // IPv6 0109 if (QHostAddress::operator==(other)) 0110 return port_number < other.port_number; 0111 else { 0112 Q_IPV6ADDR a = toIPv6Address(); 0113 Q_IPV6ADDR b = other.toIPv6Address(); 0114 for (int i = 0; i < 16; i++) { 0115 if (a[i] < b[i]) 0116 return true; 0117 else if (a[i] > b[i]) 0118 return false; 0119 } 0120 return false; 0121 } 0122 } 0123 } 0124 0125 Address &Address::operator=(const net::Address &other) 0126 { 0127 QHostAddress::operator=(other); 0128 port_number = other.port(); 0129 return *this; 0130 } 0131 0132 Address &Address::operator=(const struct sockaddr_storage &ss) 0133 { 0134 if (ss.ss_family == AF_INET) { 0135 setAddress((const struct sockaddr *)&ss); 0136 port_number = ntohs(((const struct sockaddr_in *)&ss)->sin_port); 0137 } else if (ss.ss_family == AF_INET6) { 0138 setAddress((const struct sockaddr *)&ss); 0139 port_number = ntohs(((const struct sockaddr_in6 *)&ss)->sin6_port); 0140 if (isIPv4Mapped()) { 0141 Q_IPV6ADDR ipv6 = toIPv6Address(); 0142 quint32 ip = ipv6[12] << 24 | ipv6[13] << 16 | ipv6[14] << 8 | ipv6[15]; 0143 setAddress(ip); 0144 } 0145 } 0146 0147 return *this; 0148 } 0149 0150 bool Address::isIPv4Mapped() const 0151 { 0152 Q_IPV6ADDR addr = toIPv6Address(); 0153 for (int i = 0; i < 10; i++) 0154 if (addr[i] != 0) 0155 return false; 0156 0157 return addr[10] == 0xff && addr[11] == 0xff; 0158 } 0159 0160 Address Address::convertIPv4Mapped() const 0161 { 0162 if (isIPv4Mapped()) { 0163 Q_IPV6ADDR ipv6 = toIPv6Address(); 0164 quint32 ip = ipv6[12] << 24 | ipv6[13] << 16 | ipv6[14] << 8 | ipv6[15]; 0165 return net::Address(ip, port()); 0166 } 0167 0168 return net::Address(*this); 0169 } 0170 }