]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ip/Address.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / ip / Address.h
CommitLineData
41d93087 1/*
41d93087 2 * DEBUG: section 14 IP Storage and Handling
3 * AUTHOR: Amos Jeffries
4 *
5 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
6 * ----------------------------------------------------------
7 *
8 * Squid is the result of efforts by numerous individuals from the
9 * Internet community. Development is led by Duane Wessels of the
10 * National Laboratory for Applied Network Research and funded by the
11 * National Science Foundation. Squid is Copyrighted (C) 1998 by
12 * the Regents of the University of California. Please see the
13 * COPYRIGHT file for full details. Squid incorporates software
14 * developed and/or copyrighted by other sources. Please see the
15 * CREDITS file for full details.
16 *
b7ac5457 17 * This Ip::Address code is copyright (C) 2007 by Treehouse Networks Ltd
41d93087 18 * of New Zealand. It is published and Lisenced as an extension of
19 * squid under the same conditions as the main squid application.
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
34 *
35 */
b7ac5457
AJ
36#ifndef _SQUID_IP_IPADDRESS_H
37#define _SQUID_IP_IPADDRESS_H
e1f7507e 38
41d93087 39#if HAVE_SYS_SOCKET_H
40#include <sys/socket.h>
41#endif
42#if HAVE_NETINET_IN_H
43#include <netinet/in.h>
44#endif
cdb86165
FC
45#if HAVE_NETINET_IP_H
46#include <netinet/ip.h>
47#endif
1191b93b 48#if _SQUID_MSWIN_
41d93087 49#include <ws2tcpip.h>
50#endif
489520a9 51#if HAVE_NETDB_H
41d93087 52#include <netdb.h>
53#endif
54
27e059d4 55#if HAVE_IOSFWD
41d93087 56#include <iosfwd>
27e059d4
AJ
57#endif
58#if HAVE_OSTREAM
a031cbf8 59#include <ostream>
27e059d4 60#endif
41d93087 61
63bd4bf7
A
62namespace Ip
63{
b7ac5457 64
41d93087 65/// Length of buffer that needs to be allocated to old a null-terminated IP-string
66// Yuck. But there are still structures that need it to be an 'integer constant'.
67#define MAX_IPSTRLEN 75
68
69/**
70 * Holds and manipulates IPv4, IPv6, and Socket Addresses.
71 */
b7ac5457 72class Address
41d93087 73{
74
75public:
76 /** @name Constructors and Destructor */
77 /*@{*/
3cbeddcf 78 Address() { SetEmpty(); }
b7ac5457 79 Address(const Address &);
41d93087 80
81 /**
82 * This constructor takes its own copy of the object pointed to for memory-safe usage later.
83 * The caller must itself perform and ptr memory-management needed.
84 *
85 \deprecated Use of pointers can be nasty. Consider this a last-resort.
86 * Prefer the by-reference (&) version instead.
87 */
b7ac5457 88 Address(Address *);
41d93087 89
b7ac5457 90 Address(const struct in_addr &);
b7ac5457 91 Address(const struct sockaddr_in &);
b7ac5457 92 Address(const struct in6_addr &);
b7ac5457 93 Address(const struct sockaddr_in6 &);
b7ac5457
AJ
94 Address(const struct hostent &);
95 Address(const struct addrinfo &);
96 Address(const char*);
3cbeddcf 97 ~Address() {}
41d93087 98 /*@}*/
99
100 /** @name Assignment Operators */
101 /*@{*/
b7ac5457
AJ
102 Address& operator =(const Address &s);
103 Address& operator =(struct sockaddr_in const &s);
104 Address& operator =(struct sockaddr_storage const &s);
105 Address& operator =(struct in_addr const &s);
b7ac5457
AJ
106 Address& operator =(struct in6_addr const &s);
107 Address& operator =(struct sockaddr_in6 const &s);
41d93087 108 bool operator =(const struct hostent &s);
109 bool operator =(const struct addrinfo &s);
110 bool operator =(const char *s);
111 /*@}*/
112
113 /** @name Boolean Operators */
114 /*@{*/
b7ac5457
AJ
115 bool operator ==(Address const &s) const;
116 bool operator !=(Address const &s) const;
117 bool operator >=(Address const &rhs) const;
118 bool operator <=(Address const &rhs) const;
119 bool operator >(Address const &rhs) const;
120 bool operator <(Address const &rhs) const;
41d93087 121
122public:
123 /* methods */
124
125 /** Test whether content can be used as an IPv4 address
3392646b
AJ
126 \retval true if content was received as an IPv4-Mapped address
127 \retval false if content was received as a non-mapped IPv6 native address.
41d93087 128 */
129 bool IsIPv4() const;
130
131 /** Test whether content can be used as an IPv6 address.
0906f01d
CT
132 \retval true if content is a non IPv4-mapped address.
133 \retval false if content is IPv4-mapped.
41d93087 134 */
135 bool IsIPv6() const;
136
137 /** Test whether content can be used as a Socket address.
3392646b
AJ
138 \retval true if address AND port are both set
139 \retval true if content was received as a Socket address with port
140 \retval false if port in unset (zero)
41d93087 141 */
142 bool IsSockAddr() const;
143
144 /** Content-neutral test for whether the specific IP case ANY_ADDR is stored.
b7ac5457 145 * This is the default content of a new undefined Ip::Address object.
3392646b
AJ
146 \retval true IPv4 0.0.0.0
147 \retval true IPv6 ::
148 \retval false anything else.
41d93087 149 */
150 bool IsAnyAddr() const;
151
152 /** Content-neutral test for whether the specific IP case NO_ADDR is stored.
3392646b
AJ
153 \retval true IPv4 255.255.255.255
154 \retval true IPv6 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
155 \retval false anything else.
41d93087 156 */
157 bool IsNoAddr() const;
158
159 /** Content-neutral test for whether the specific IP case LOCALHOST is stored.
b7ac5457 160 * This is the default content of a new undefined Ip::Address object.
3392646b
AJ
161 \retval true IPv4 127.0.0.1
162 \retval true IPv6 ::1
163 \retval false anything else.
41d93087 164 */
165 bool IsLocalhost() const;
166
a98c2da5 167 /** Test whether content is an IPv6 Site-Local address.
dd19b634 168 \retval true if address begins with fd00::/8.
a98c2da5 169 \retval false if --disable-ipv6 has been compiled.
dd19b634 170 \retval false if address does not match fd00::/8
a98c2da5
AJ
171 */
172 bool IsSiteLocal6() const;
173
174 /** Test whether content is an IPv6 address with SLAAC EUI-64 embeded.
175 \retval true if address matches ::ff:fe00:0
176 \retval false if --disable-ipv6 has been compiled.
177 \retval false if address does not match ::ff:fe00:0
178 */
179 bool IsSlaac() const;
180
41d93087 181 /*@}*/
182
183 /** Retrieve the Port if stored.
3392646b
AJ
184 \retval 0 Port is unset or an error occured.
185 \retval n Port associated with this address in host native -endian.
41d93087 186 */
f45dd259 187 unsigned short GetPort() const;
41d93087 188
189 /** Set the Port value for an address.
190 * Replaces any previously existing Port value.
3392646b
AJ
191 \param port Port being assigned in host native -endian.
192 \retval 0 Port is unset or an error occured.
193 \retval n Port associated with this address in host native -endian.
41d93087 194 */
f45dd259 195 unsigned short SetPort(unsigned short port);
41d93087 196
197 /// Set object to contain the specific IP case ANY_ADDR (format-neutral).
198 /// see IsAnyAddr() for more detail.
199 void SetAnyAddr();
200
201 /// Set object to contain the specific IP case NO_ADDR (format-neutral).
d85b8894 202 /// see IsNoAddr() for more detail.
41d93087 203 void SetNoAddr();
204
205 /// Set object to contain the specific IP case LOCALHOST (format-neutral).
d85b8894 206 /// see IsLocalhost() for more detail.
41d93087 207 void SetLocalhost();
208
209 /// Fast reset of the stored content to what would be after default constructor.
210 void SetEmpty();
211
212 /** Require an IPv4-only address for this usage.
213 * Converts the object to prefer only IPv4 output.
214 \retval true Content can be IPv4
215 \retval false Content CANNOT be IPv4
216 */
217 bool SetIPv4();
218
219 /**
220 * Valid results IF and only IF the stored IP address is actually a network bitmask
3392646b 221 \retval N number of bits which are set in the bitmask stored.
41d93087 222 */
df9617b9 223 int GetCIDR() const;
41d93087 224
225 /** Apply a mask to the stored address.
3392646b 226 \param mask Netmask format to be bit-mask-AND'd over the stored address.
41d93087 227 */
881c4733 228 int ApplyMask(const Address &mask);
41d93087 229
230 /** Apply a mask to the stored address.
231 * CIDR will be converted appropriate to map the stored content.
3392646b
AJ
232 \param cidr CIDR Mask being applied. As an integer in host format.
233 \param mtype Type of CIDR mask being applied (AF_INET or AF_INET6)
41d93087 234 */
055421ee 235 bool ApplyMask(const unsigned int cidr, int mtype);
41d93087 236
41d93087 237 /** Return the ASCII equivalent of the address
238 * Semantically equivalent to the IPv4 inet_ntoa()
239 * eg. 127.0.0.1 (IPv4) or ::1 (IPv6)
240 * But for memory safety it requires a buffer as input
241 * instead of producing one magically.
242 * If buffer is not large enough the data is truncated silently.
3392646b
AJ
243 \param buf Allocated buffer to write address to
244 \param len byte length of buffer available for writing.
245 \param force (optional) require the IPA in a specific format.
246 \return pointer to buffer received.
41d93087 247 */
b62b752c 248 char* NtoA(char *buf, const unsigned int blen, int force = AF_UNSPEC) const;
41d93087 249
250 /** Return the ASCII equivalent of the address:port combination
251 * Provides a URL formatted version of the content.
252 * If buffer is not large enough the data is truncated silently.
253 * eg. 127.0.0.1:80 (IPv4) or [::1]:80 (IPv6)
3392646b
AJ
254 \param buf Allocated buffer to write address:port to
255 \param len byte length of buffer available for writing.
256 \return pointer to buffer received.
41d93087 257 */
258 char* ToURL(char *buf, unsigned int len) const;
259
260 /** Return a properly hostname formatted copy of the address
261 * Provides a URL formatted version of the content.
262 * If buffer is not large enough the data is truncated silently.
263 * eg. 127.0.0.1 (IPv4) or [::1] (IPv6)
3392646b
AJ
264 \param buf Allocated buffer to write address to
265 \param len byte length of buffer available for writing.
de12d836 266 \return amount of buffer filled.
41d93087 267 */
268 unsigned int ToHostname(char *buf, const unsigned int len) const;
269
3392646b 270 /**
41d93087 271 * Convert the content into a Reverse-DNS string.
272 * The buffer sent MUST be allocated large enough to hold the resulting string.
273 * Name truncation will occur if buf does not have enough space.
274 * The constant MAX_IPSTRLEN is defined to provide for sizing arrays correctly.
d85b8894
AJ
275 \param show_type may be one of: AF_INET, AF_INET6 for the format of rDNS string wanted.
276 * AF_UNSPEC the default displays the IP in its most advanced native form.
277 \param buf buffer to receive the text string output.
41d93087 278 */
d85b8894 279 bool GetReverseString(char buf[MAX_IPSTRLEN], int show_type = AF_UNSPEC) const;
41d93087 280
281 /** Test how two IP relate to each other.
3392646b
AJ
282 \retval 0 IP are equal
283 \retval 1 IP rhs is greater (numerically) than that stored.
284 \retval -1 IP rhs is less (numerically) than that stored.
41d93087 285 */
b7ac5457 286 int matchIPAddr(const Address &rhs) const;
41d93087 287
607a7bd4
AR
288 /** Compare taking IP, port, protocol, etc. into account. Returns an
289 integer less than, equal to, or greater than zero if the object
290 is found, respectively, to be less than, to match, or to be greater
291 than rhs. The exact ordering algorithm is not specified and may change.
292 */
a67d2b2e 293 int compareWhole(const Ip::Address &rhs) const;
607a7bd4 294
41d93087 295 /**
b7ac5457 296 * Get RFC 3493 addrinfo structure from the Ip::Address data
41d93087 297 * for protocol-neutral socket operations.
298 * Should be passed a NULL pointer of type struct addrinfo* it will
299 * allocate memory for the structures involved. (see FreeAddrInfo to clear).
300 * Defaults to a TCP streaming socket, if other values (such as UDP) are needed
301 * the caller MUST override these default settings.
302 * Some situations may also require an actual call to the system getaddrinfo()
303 * to pull relevant OS details for the socket.
3392646b 304 \par
b7ac5457 305 * Ip::Address allocated objects MUST be destructed by Ip::Address::FreeAddrInfo
41d93087 306 * System getaddrinfo() allocated objects MUST be freed with system freeaddrinfo()
41d93087 307 *
3392646b
AJ
308 \param ai structure to be filled out.
309 \param force a specific sockaddr type is needed. default: don't care.
41d93087 310 */
41d93087 311 void GetAddrInfo(struct addrinfo *&ai, int force = AF_UNSPEC) const;
41d93087 312
313 /**
b7ac5457 314 * Equivalent to the sysem call freeaddrinfo() but for Ip::Address allocated data
41d93087 315 */
b7ac5457 316 static void FreeAddrInfo(struct addrinfo *&ai);
41d93087 317
318 /**
319 * Initializes an empty addrinfo properly for use.
320 * It is intended for use in cases such as getsockopt() where the addrinfo is
321 * about to be changed and the stored details may not match the new ones coming.
3392646b 322 \param ai addrinfo struct to be initialized as AF_UNSPEC with large address buffer
41d93087 323 */
b7ac5457 324 static void InitAddrInfo(struct addrinfo *&ai);
41d93087 325
326 /**
327 * Lookup a Host by Name. Equivalent to system call gethostbyname(char*)
3392646b
AJ
328 \param s The textual FQDN of the host being located.
329 \retval true lookup was successful and an IPA was located.
330 \retval false lookup failed or FQDN has no IP associated.
41d93087 331 */
332 bool GetHostByName(const char *s);
333
334public:
335 /* FIXME: When C => C++ conversion is done will be fully private.
336 * Legacy Transition Methods.
337 * These are here solely to simplify the transition
338 * when moving from converted code to unconverted
339 * these functions can be used to convert this object
340 * and pull out the data needed by the unconverted code
341 * they are intentionaly hard to use, use GetAddrInfo() instead.
342 * these functiosn WILL NOT be in the final public API after transition.
343 */
344
0e1a47f0 345 void GetSockAddr(struct sockaddr_storage &addr, const int family) const;
41d93087 346 void GetSockAddr(struct sockaddr_in &) const;
41d93087 347 bool GetInAddr(struct in_addr &) const; /* false if could not convert IPv6 down to IPv4 */
41d93087 348 void GetSockAddr(struct sockaddr_in6 &) const;
41d93087 349 void GetInAddr(struct in6_addr &) const;
41d93087 350
351private:
352 /* Conversion for dual-type internals */
353
d85b8894 354 bool GetReverseString4(char buf[MAX_IPSTRLEN], const struct in_addr &dat) const;
41d93087 355
d85b8894 356 bool GetReverseString6(char buf[MAX_IPSTRLEN], const struct in6_addr &dat) const;
41d93087 357
358 void Map4to6(const struct in_addr &src, struct in6_addr &dest) const;
359
360 void Map6to4(const struct in6_addr &src, struct in_addr &dest) const;
41d93087 361
362 // Worker behind GetHostName and char* converters
363 bool LookupHostIP(const char *s, bool nodns);
364
365 /* variables */
41d93087 366 struct sockaddr_in6 m_SocketAddr;
c0248e14
HN
367
368private:
369 /* Internally used constants */
370 static const unsigned int STRLEN_IP4A = 16; // aaa.bbb.ccc.ddd\0
371 static const unsigned int STRLEN_IP4R = 28; // ddd.ccc.bbb.aaa.in-addr.arpa.\0
372 static const unsigned int STRLEN_IP4S = 21; // ddd.ccc.bbb.aaa:ppppp\0
373 static const unsigned int MAX_IP4_STRLEN = STRLEN_IP4R;
c0248e14
HN
374 static const unsigned int STRLEN_IP6A = 42; // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/0
375 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
376 static const unsigned int STRLEN_IP6S = 48; // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:00000/0
377 static const unsigned int MAX_IP6_STRLEN = STRLEN_IP6R;
378 static const struct in6_addr v4_localhost;
379 static const struct in6_addr v4_anyaddr;
0eb08770 380 static const struct in6_addr v4_noaddr;
c0248e14 381 static const struct in6_addr v6_noaddr;
41d93087 382};
383
384inline std::ostream &
b7ac5457 385operator << (std::ostream &os, const Address &ipa)
41d93087 386{
387 char buf[MAX_IPSTRLEN];
388 os << ipa.ToURL(buf,MAX_IPSTRLEN);
389 return os;
390}
391
41d93087 392// WAS _sockaddr_in_list in an earlier incarnation
b7ac5457 393class Address_list
41d93087 394{
395public:
b7ac5457
AJ
396 Address_list() { next = NULL; };
397 ~Address_list() { if (next) delete next; next = NULL; };
41d93087 398
b7ac5457
AJ
399 Address s;
400 Address_list *next;
41d93087 401};
402
e5519212 403} // namespace Ip
b7ac5457
AJ
404
405extern void parse_IpAddress_list_token(Ip::Address_list **, char *);
41d93087 406
b7ac5457 407#endif /* _SQUID_IP_IPADDRESS_H */