]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ip/Address.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ip / Address.h
CommitLineData
41d93087 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
bbc27441
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
41d93087 7 */
bbc27441
AJ
8
9/* DEBUG: section 14 IP Storage and Handling */
10
4dd643d5
AJ
11#ifndef _SQUID_SRC_IP_ADDRESS_H
12#define _SQUID_SRC_IP_ADDRESS_H
e1f7507e 13
1a7cfe02
AJ
14#include "ip/forward.h"
15
074d6a40
AJ
16#include <iosfwd>
17#include <ostream>
41d93087 18#if HAVE_SYS_SOCKET_H
19#include <sys/socket.h>
20#endif
21#if HAVE_NETINET_IN_H
22#include <netinet/in.h>
23#endif
cdb86165
FC
24#if HAVE_NETINET_IP_H
25#include <netinet/ip.h>
26#endif
7aa9bb3e 27#if HAVE_WS2TCPIP_H
41d93087 28#include <ws2tcpip.h>
29#endif
489520a9 30#if HAVE_NETDB_H
41d93087 31#include <netdb.h>
32#endif
33
63bd4bf7
A
34namespace Ip
35{
b7ac5457 36
41d93087 37/**
38 * Holds and manipulates IPv4, IPv6, and Socket Addresses.
39 */
b7ac5457 40class Address
41d93087 41{
42
43public:
4c218615 44 /** @name Constructors */
41d93087 45 /*@{*/
4dd643d5 46 Address() { setEmpty(); }
b7ac5457 47 Address(const struct in_addr &);
b7ac5457 48 Address(const struct sockaddr_in &);
b7ac5457 49 Address(const struct in6_addr &);
b7ac5457 50 Address(const struct sockaddr_in6 &);
b7ac5457
AJ
51 Address(const struct hostent &);
52 Address(const struct addrinfo &);
53 Address(const char*);
41d93087 54 /*@}*/
55
56 /** @name Assignment Operators */
57 /*@{*/
b7ac5457
AJ
58 Address& operator =(struct sockaddr_in const &s);
59 Address& operator =(struct sockaddr_storage const &s);
60 Address& operator =(struct in_addr const &s);
b7ac5457
AJ
61 Address& operator =(struct in6_addr const &s);
62 Address& operator =(struct sockaddr_in6 const &s);
41d93087 63 bool operator =(const struct hostent &s);
64 bool operator =(const struct addrinfo &s);
65 bool operator =(const char *s);
66 /*@}*/
67
68 /** @name Boolean Operators */
69 /*@{*/
b7ac5457
AJ
70 bool operator ==(Address const &s) const;
71 bool operator !=(Address const &s) const;
72 bool operator >=(Address const &rhs) const;
73 bool operator <=(Address const &rhs) const;
74 bool operator >(Address const &rhs) const;
75 bool operator <(Address const &rhs) const;
41d93087 76
77public:
78 /* methods */
79
80 /** Test whether content can be used as an IPv4 address
3392646b
AJ
81 \retval true if content was received as an IPv4-Mapped address
82 \retval false if content was received as a non-mapped IPv6 native address.
41d93087 83 */
4dd643d5 84 bool isIPv4() const;
41d93087 85
86 /** Test whether content can be used as an IPv6 address.
0906f01d
CT
87 \retval true if content is a non IPv4-mapped address.
88 \retval false if content is IPv4-mapped.
41d93087 89 */
4dd643d5 90 bool isIPv6() const;
41d93087 91
92 /** Test whether content can be used as a Socket address.
3392646b
AJ
93 \retval true if address AND port are both set
94 \retval true if content was received as a Socket address with port
95 \retval false if port in unset (zero)
41d93087 96 */
4dd643d5 97 bool isSockAddr() const;
41d93087 98
99 /** Content-neutral test for whether the specific IP case ANY_ADDR is stored.
b7ac5457 100 * This is the default content of a new undefined Ip::Address object.
3392646b
AJ
101 \retval true IPv4 0.0.0.0
102 \retval true IPv6 ::
103 \retval false anything else.
41d93087 104 */
4dd643d5 105 bool isAnyAddr() const;
41d93087 106
107 /** Content-neutral test for whether the specific IP case NO_ADDR is stored.
3392646b
AJ
108 \retval true IPv4 255.255.255.255
109 \retval true IPv6 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
110 \retval false anything else.
41d93087 111 */
4dd643d5 112 bool isNoAddr() const;
41d93087 113
114 /** Content-neutral test for whether the specific IP case LOCALHOST is stored.
b7ac5457 115 * This is the default content of a new undefined Ip::Address object.
3392646b
AJ
116 \retval true IPv4 127.0.0.1
117 \retval true IPv6 ::1
118 \retval false anything else.
41d93087 119 */
4dd643d5 120 bool isLocalhost() const;
41d93087 121
a98c2da5 122 /** Test whether content is an IPv6 Site-Local address.
dd19b634 123 \retval true if address begins with fd00::/8.
a98c2da5 124 \retval false if --disable-ipv6 has been compiled.
dd19b634 125 \retval false if address does not match fd00::/8
a98c2da5 126 */
4dd643d5 127 bool isSiteLocal6() const;
a98c2da5 128
2f8abb64 129 /** Test whether content is an IPv6 address with SLAAC EUI-64 embedded.
a98c2da5
AJ
130 \retval true if address matches ::ff:fe00:0
131 \retval false if --disable-ipv6 has been compiled.
132 \retval false if address does not match ::ff:fe00:0
133 */
4dd643d5 134 bool isSiteLocalAuto() const;
a98c2da5 135
41d93087 136 /*@}*/
137
138 /** Retrieve the Port if stored.
61beade2 139 \retval 0 Port is unset or an error occurred.
3392646b 140 \retval n Port associated with this address in host native -endian.
41d93087 141 */
4dd643d5 142 unsigned short port() const;
41d93087 143
144 /** Set the Port value for an address.
145 * Replaces any previously existing Port value.
3392646b 146 \param port Port being assigned in host native -endian.
61beade2 147 \retval 0 Port is unset or an error occurred.
3392646b 148 \retval n Port associated with this address in host native -endian.
41d93087 149 */
4dd643d5 150 unsigned short port(unsigned short port);
41d93087 151
152 /// Set object to contain the specific IP case ANY_ADDR (format-neutral).
4dd643d5
AJ
153 /// see isAnyAddr() for more detail.
154 void setAnyAddr();
41d93087 155
156 /// Set object to contain the specific IP case NO_ADDR (format-neutral).
4dd643d5
AJ
157 /// see isNoAddr() for more detail.
158 void setNoAddr();
41d93087 159
160 /// Set object to contain the specific IP case LOCALHOST (format-neutral).
4dd643d5
AJ
161 /// see isLocalhost() for more detail.
162 void setLocalhost();
41d93087 163
164 /// Fast reset of the stored content to what would be after default constructor.
4dd643d5 165 void setEmpty();
41d93087 166
167 /** Require an IPv4-only address for this usage.
168 * Converts the object to prefer only IPv4 output.
f53969cc
SM
169 \retval true Content can be IPv4
170 \retval false Content CANNOT be IPv4
41d93087 171 */
4dd643d5 172 bool setIPv4();
41d93087 173
174 /**
175 * Valid results IF and only IF the stored IP address is actually a network bitmask
3392646b 176 \retval N number of bits which are set in the bitmask stored.
41d93087 177 */
4dd643d5 178 int cidr() const;
41d93087 179
180 /** Apply a mask to the stored address.
3392646b 181 \param mask Netmask format to be bit-mask-AND'd over the stored address.
41d93087 182 */
4dd643d5 183 int applyMask(const Address &mask);
41d93087 184
185 /** Apply a mask to the stored address.
186 * CIDR will be converted appropriate to map the stored content.
3392646b
AJ
187 \param cidr CIDR Mask being applied. As an integer in host format.
188 \param mtype Type of CIDR mask being applied (AF_INET or AF_INET6)
41d93087 189 */
4dd643d5 190 bool applyMask(const unsigned int cidr, int mtype);
41d93087 191
36c774f7
EB
192 /// Apply so-called 'privacy masking' to IPv4 addresses,
193 /// except localhost IP.
194 /// IPv6 clients use 'privacy addressing' instead.
195 void applyClientMask(const Address &mask);
196
41d93087 197 /** Return the ASCII equivalent of the address
198 * Semantically equivalent to the IPv4 inet_ntoa()
199 * eg. 127.0.0.1 (IPv4) or ::1 (IPv6)
200 * But for memory safety it requires a buffer as input
201 * instead of producing one magically.
202 * If buffer is not large enough the data is truncated silently.
3392646b
AJ
203 \param buf Allocated buffer to write address to
204 \param len byte length of buffer available for writing.
205 \param force (optional) require the IPA in a specific format.
206 \return pointer to buffer received.
41d93087 207 */
4dd643d5 208 char* toStr(char *buf, const unsigned int blen, int force = AF_UNSPEC) const;
41d93087 209
210 /** Return the ASCII equivalent of the address:port combination
211 * Provides a URL formatted version of the content.
212 * If buffer is not large enough the data is truncated silently.
213 * eg. 127.0.0.1:80 (IPv4) or [::1]:80 (IPv6)
3392646b
AJ
214 \param buf Allocated buffer to write address:port to
215 \param len byte length of buffer available for writing.
216 \return pointer to buffer received.
41d93087 217 */
4dd643d5 218 char* toUrl(char *buf, unsigned int len) const;
41d93087 219
220 /** Return a properly hostname formatted copy of the address
221 * Provides a URL formatted version of the content.
222 * If buffer is not large enough the data is truncated silently.
223 * eg. 127.0.0.1 (IPv4) or [::1] (IPv6)
3392646b
AJ
224 \param buf Allocated buffer to write address to
225 \param len byte length of buffer available for writing.
de12d836 226 \return amount of buffer filled.
41d93087 227 */
4dd643d5 228 unsigned int toHostStr(char *buf, const unsigned int len) const;
41d93087 229
fd9c47d1
AR
230 /// Empties the address and then slowly imports the IP from a possibly
231 /// [bracketed] portless host. For the semi-reverse operation, see
232 /// toHostStr() which does export the port.
233 /// \returns whether the conversion was successful
234 bool fromHost(const char *hostWithoutPort);
235
3392646b 236 /**
41d93087 237 * Convert the content into a Reverse-DNS string.
238 * The buffer sent MUST be allocated large enough to hold the resulting string.
239 * Name truncation will occur if buf does not have enough space.
240 * The constant MAX_IPSTRLEN is defined to provide for sizing arrays correctly.
d85b8894
AJ
241 \param show_type may be one of: AF_INET, AF_INET6 for the format of rDNS string wanted.
242 * AF_UNSPEC the default displays the IP in its most advanced native form.
243 \param buf buffer to receive the text string output.
41d93087 244 */
4dd643d5 245 bool getReverseString(char buf[MAX_IPSTRLEN], int show_type = AF_UNSPEC) const;
41d93087 246
247 /** Test how two IP relate to each other.
3392646b
AJ
248 \retval 0 IP are equal
249 \retval 1 IP rhs is greater (numerically) than that stored.
250 \retval -1 IP rhs is less (numerically) than that stored.
41d93087 251 */
b7ac5457 252 int matchIPAddr(const Address &rhs) const;
41d93087 253
607a7bd4
AR
254 /** Compare taking IP, port, protocol, etc. into account. Returns an
255 integer less than, equal to, or greater than zero if the object
256 is found, respectively, to be less than, to match, or to be greater
257 than rhs. The exact ordering algorithm is not specified and may change.
258 */
a67d2b2e 259 int compareWhole(const Ip::Address &rhs) const;
607a7bd4 260
41d93087 261 /**
b7ac5457 262 * Get RFC 3493 addrinfo structure from the Ip::Address data
41d93087 263 * for protocol-neutral socket operations.
264 * Should be passed a NULL pointer of type struct addrinfo* it will
851614a8 265 * allocate memory for the structures involved. (see FreeAddr() to clear).
41d93087 266 * Defaults to a TCP streaming socket, if other values (such as UDP) are needed
267 * the caller MUST override these default settings.
268 * Some situations may also require an actual call to the system getaddrinfo()
269 * to pull relevant OS details for the socket.
3392646b 270 \par
851614a8 271 * Ip::Address allocated objects MUST be destructed by Ip::Address::FreeAddr
41d93087 272 * System getaddrinfo() allocated objects MUST be freed with system freeaddrinfo()
41d93087 273 *
3392646b
AJ
274 \param ai structure to be filled out.
275 \param force a specific sockaddr type is needed. default: don't care.
41d93087 276 */
4dd643d5 277 void getAddrInfo(struct addrinfo *&ai, int force = AF_UNSPEC) const;
41d93087 278
279 /**
b7ac5457 280 * Equivalent to the sysem call freeaddrinfo() but for Ip::Address allocated data
41d93087 281 */
851614a8 282 static void FreeAddr(struct addrinfo *&ai);
41d93087 283
284 /**
285 * Initializes an empty addrinfo properly for use.
286 * It is intended for use in cases such as getsockopt() where the addrinfo is
287 * about to be changed and the stored details may not match the new ones coming.
3392646b 288 \param ai addrinfo struct to be initialized as AF_UNSPEC with large address buffer
41d93087 289 */
851614a8 290 static void InitAddr(struct addrinfo *&ai);
41d93087 291
292 /**
293 * Lookup a Host by Name. Equivalent to system call gethostbyname(char*)
3392646b 294 \param s The textual FQDN of the host being located.
f53969cc
SM
295 \retval true lookup was successful and an IPA was located.
296 \retval false lookup failed or FQDN has no IP associated.
41d93087 297 */
298 bool GetHostByName(const char *s);
299
7976fed3
EB
300 /// \returns an Address with true isNoAddr()
301 /// \see isNoAddr() for more details
302 static const Address &NoAddr() { static const Address noAddr(v6_noaddr); return noAddr; }
303
41d93087 304public:
9837567d 305 /* XXX: When C => C++ conversion is done will be fully private.
41d93087 306 * Legacy Transition Methods.
307 * These are here solely to simplify the transition
308 * when moving from converted code to unconverted
309 * these functions can be used to convert this object
310 * and pull out the data needed by the unconverted code
4dd643d5 311 * they are intentionaly hard to use, use getAddrInfo() instead.
2f8abb64 312 * these functions WILL NOT be in the final public API after transition.
41d93087 313 */
314
4dd643d5
AJ
315 void getSockAddr(struct sockaddr_storage &addr, const int family) const;
316 void getSockAddr(struct sockaddr_in &) const;
317 bool getInAddr(struct in_addr &) const; /* false if could not convert IPv6 down to IPv4 */
318 void getSockAddr(struct sockaddr_in6 &) const;
319 void getInAddr(struct in6_addr &) const;
41d93087 320
321private:
322 /* Conversion for dual-type internals */
323
4dd643d5 324 bool getReverseString4(char buf[MAX_IPSTRLEN], const struct in_addr &dat) const;
41d93087 325
4dd643d5 326 bool getReverseString6(char buf[MAX_IPSTRLEN], const struct in6_addr &dat) const;
41d93087 327
4dd643d5 328 void map4to6(const struct in_addr &src, struct in6_addr &dest) const;
41d93087 329
4dd643d5 330 void map6to4(const struct in6_addr &src, struct in_addr &dest) const;
41d93087 331
332 // Worker behind GetHostName and char* converters
4dd643d5 333 bool lookupHostIP(const char *s, bool nodns);
41d93087 334
335 /* variables */
4dd643d5 336 struct sockaddr_in6 mSocketAddr_;
c0248e14
HN
337
338private:
339 /* Internally used constants */
340 static const unsigned int STRLEN_IP4A = 16; // aaa.bbb.ccc.ddd\0
341 static const unsigned int STRLEN_IP4R = 28; // ddd.ccc.bbb.aaa.in-addr.arpa.\0
342 static const unsigned int STRLEN_IP4S = 21; // ddd.ccc.bbb.aaa:ppppp\0
343 static const unsigned int MAX_IP4_STRLEN = STRLEN_IP4R;
c0248e14
HN
344 static const unsigned int STRLEN_IP6A = 42; // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/0
345 static const unsigned int STRLEN_IP6R = 75; // f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f f.f.f.f ipv6.arpa./0
346 static const unsigned int STRLEN_IP6S = 48; // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:00000/0
347 static const unsigned int MAX_IP6_STRLEN = STRLEN_IP6R;
348 static const struct in6_addr v4_localhost;
349 static const struct in6_addr v4_anyaddr;
0eb08770 350 static const struct in6_addr v4_noaddr;
c0248e14 351 static const struct in6_addr v6_noaddr;
41d93087 352};
353
354inline std::ostream &
b7ac5457 355operator << (std::ostream &os, const Address &ipa)
41d93087 356{
357 char buf[MAX_IPSTRLEN];
4dd643d5 358 os << ipa.toUrl(buf,MAX_IPSTRLEN);
41d93087 359 return os;
360}
361
41d93087 362// WAS _sockaddr_in_list in an earlier incarnation
b7ac5457 363class Address_list
41d93087 364{
365public:
b7ac5457
AJ
366 Address_list() { next = NULL; };
367 ~Address_list() { if (next) delete next; next = NULL; };
41d93087 368
b7ac5457
AJ
369 Address s;
370 Address_list *next;
41d93087 371};
372
e5519212 373} // namespace Ip
b7ac5457 374
82afb125 375void parse_IpAddress_list_token(Ip::Address_list **, char *);
41d93087 376
4dd643d5 377#endif /* _SQUID_SRC_IP_ADDRESS_H */
f53969cc 378