Line data Source code
1 : // Network Address -- classes functions to ease handling IP addresses
2 : // Copyright (C) 2012-2017 Made to Order Software Corp.
3 : //
4 : // http://snapwebsites.org/project/libaddr
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : #pragma once
20 :
21 : /** \file
22 : * \brief The various libaddr classes.
23 : *
24 : * This header includes the base addr class used to handle one binary
25 : * address.
26 : */
27 :
28 : // C++ library
29 : //
30 : #include <memory>
31 : #include <cstring>
32 : #include <vector>
33 :
34 : // C library
35 : //
36 : #include <arpa/inet.h>
37 :
38 :
39 :
40 : namespace addr
41 : {
42 :
43 :
44 :
45 :
46 : /** \brief Initialize an IPv6 address as such.
47 : *
48 : * This function initializes a sockaddr_in6 with all zeroes except
49 : * for the sin6_family which is set to AF_INET6.
50 : *
51 : * return The initialized IPv6 address.
52 : */
53 396042 : constexpr struct sockaddr_in6 init_in6()
54 : {
55 396042 : struct sockaddr_in6 in6 = sockaddr_in6();
56 396042 : in6.sin6_family = AF_INET6;
57 396042 : return in6;
58 : }
59 :
60 :
61 1320610 : class addr
62 : {
63 : public:
64 : enum class network_type_t
65 : {
66 : NETWORK_TYPE_UNDEFINED,
67 : NETWORK_TYPE_PRIVATE,
68 : NETWORK_TYPE_CARRIER,
69 : NETWORK_TYPE_LINK_LOCAL,
70 : NETWORK_TYPE_MULTICAST,
71 : NETWORK_TYPE_LOOPBACK,
72 : NETWORK_TYPE_ANY,
73 : NETWORK_TYPE_UNKNOWN,
74 : NETWORK_TYPE_PUBLIC = NETWORK_TYPE_UNKNOWN // we currently do not distinguish public and unknown
75 : };
76 :
77 : enum class computer_interface_address_t
78 : {
79 : COMPUTER_INTERFACE_ADDRESS_ERROR = -1,
80 : COMPUTER_INTERFACE_ADDRESS_FALSE,
81 : COMPUTER_INTERFACE_ADDRESS_TRUE
82 : };
83 :
84 : enum class string_ip_t
85 : {
86 : STRING_IP_ONLY,
87 : STRING_IP_BRACKETS, // IPv6 only
88 : STRING_IP_PORT,
89 : STRING_IP_MASK,
90 : STRING_IP_BRACKETS_MASK, // IPv6 only
91 : STRING_IP_ALL
92 : };
93 :
94 : typedef std::shared_ptr<addr> pointer_t;
95 : typedef std::vector<addr> vector_t;
96 : typedef int socket_flag_t;
97 :
98 : static socket_flag_t const SOCKET_FLAG_CLOEXEC = 0x01;
99 : static socket_flag_t const SOCKET_FLAG_NONBLOCK = 0x02;
100 : static socket_flag_t const SOCKET_FLAG_REUSE = 0x04;
101 :
102 : addr();
103 : addr(struct sockaddr_in const & in);
104 : addr(struct sockaddr_in6 const & in6);
105 :
106 : static vector_t get_local_addresses();
107 :
108 : void set_from_socket(int s, bool peer);
109 : void set_ipv4(struct sockaddr_in const & in);
110 : void set_ipv6(struct sockaddr_in6 const & in6);
111 : void set_port(int port);
112 : void set_protocol(char const * protocol);
113 : void set_protocol(int protocol);
114 : void set_mask(uint8_t const * mask);
115 : void apply_mask();
116 :
117 : bool is_ipv4() const;
118 : void get_ipv4(struct sockaddr_in & in) const;
119 : void get_ipv6(struct sockaddr_in6 & in6) const;
120 : std::string to_ipv4_string(string_ip_t mode) const;
121 : std::string to_ipv6_string(string_ip_t mode) const;
122 : std::string to_ipv4or6_string(string_ip_t mode) const;
123 :
124 : network_type_t get_network_type() const;
125 : std::string get_network_type_string() const;
126 : computer_interface_address_t is_computer_interface_address() const;
127 :
128 : std::string get_iface_name() const;
129 : int create_socket(socket_flag_t flags) const;
130 : int connect(int s) const;
131 : int bind(int s) const;
132 : std::string get_name() const;
133 : std::string get_service() const;
134 : int get_port() const;
135 : int get_protocol() const;
136 : void get_mask(uint8_t * mask);
137 :
138 : bool match(addr const & ip) const;
139 : bool operator == (addr const & rhs) const;
140 : bool operator != (addr const & rhs) const;
141 : bool operator < (addr const & rhs) const;
142 : bool operator <= (addr const & rhs) const;
143 : bool operator > (addr const & rhs) const;
144 : bool operator >= (addr const & rhs) const;
145 :
146 : private:
147 : void address_changed();
148 :
149 : // always keep address in an IPv6 structure
150 : //
151 : struct sockaddr_in6 f_address = init_in6();
152 : uint8_t f_mask[16] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
153 : std::string f_iface_name;
154 : int f_protocol = IPPROTO_TCP;
155 : mutable network_type_t f_private_network_defined = network_type_t::NETWORK_TYPE_UNDEFINED;
156 : };
157 :
158 :
159 :
160 :
161 :
162 : }
163 : // addr namespace
164 :
165 :
166 : inline bool operator == (struct sockaddr_in6 const & a, struct sockaddr_in6 const & b)
167 : {
168 : return memcmp(&a, &b, sizeof(struct sockaddr_in6)) == 0;
169 : }
170 :
171 :
172 : inline bool operator != (struct sockaddr_in6 const & a, struct sockaddr_in6 const & b)
173 : {
174 : return memcmp(&a, &b, sizeof(struct sockaddr_in6)) != 0;
175 : }
176 :
177 :
178 : inline bool operator < (struct sockaddr_in6 const & a, struct sockaddr_in6 const & b)
179 : {
180 : return memcmp(&a, &b, sizeof(struct sockaddr_in6)) < 0;
181 : }
182 :
183 :
184 : inline bool operator <= (struct sockaddr_in6 const & a, struct sockaddr_in6 const & b)
185 : {
186 : return memcmp(&a, &b, sizeof(struct sockaddr_in6)) <= 0;
187 : }
188 :
189 :
190 : inline bool operator > (struct sockaddr_in6 const & a, struct sockaddr_in6 const & b)
191 : {
192 : return memcmp(&a, &b, sizeof(struct sockaddr_in6)) > 0;
193 : }
194 :
195 :
196 : inline bool operator >= (struct sockaddr_in6 const & a, struct sockaddr_in6 const & b)
197 : {
198 : return memcmp(&a, &b, sizeof(struct sockaddr_in6)) >= 0;
199 : }
200 :
201 :
202 35 : inline bool operator == (in6_addr const & a, in6_addr const & b)
203 : {
204 35 : return memcmp(&a, &b, sizeof(in6_addr)) == 0;
205 : }
206 :
207 :
208 9 : inline bool operator != (in6_addr const & a, in6_addr const & b)
209 : {
210 9 : return memcmp(&a, &b, sizeof(in6_addr)) != 0;
211 : }
212 :
213 :
214 7 : inline bool operator < (in6_addr const & a, in6_addr const & b)
215 : {
216 7 : return memcmp(&a, &b, sizeof(in6_addr)) < 0;
217 : }
218 :
219 :
220 685 : inline bool operator <= (in6_addr const & a, in6_addr const & b)
221 : {
222 685 : return memcmp(&a, &b, sizeof(in6_addr)) <= 0;
223 : }
224 :
225 :
226 27 : inline bool operator > (in6_addr const & a, in6_addr const & b)
227 : {
228 27 : return memcmp(&a, &b, sizeof(in6_addr)) > 0;
229 : }
230 :
231 :
232 290 : inline bool operator >= (in6_addr const & a, in6_addr const & b)
233 : {
234 290 : return memcmp(&a, &b, sizeof(in6_addr)) >= 0;
235 : }
236 :
237 :
238 : // vim: ts=4 sw=4 et
|