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