Panda3D
socket_address.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file socket_address.I
10  * @author rdb
11  * @date 2014-10-19
12  */
13 
14 #include "pnotify.h"
15 
16 /**
17  * Constructor that lets us set a port value
18  */
19 INLINE Socket_Address::
20 Socket_Address(unsigned short port) {
21  _addr4.sin_family = AF_INET;
22  _addr4.sin_addr.s_addr = INADDR_ANY;
23  _addr4.sin_port = htons(port);
24 }
25 
26 /**
27  *
28  */
29 INLINE Socket_Address::
30 Socket_Address(const Socket_Address &inaddr) :
31  _storage(inaddr._storage) {
32 }
33 
34 /**
35  *
36  */
37 INLINE Socket_Address::
38 Socket_Address(const struct sockaddr &inaddr) {
39  if (inaddr.sa_family == AF_INET) {
40  _addr4 = (const sockaddr_in &)inaddr;
41 
42  } else if (inaddr.sa_family == AF_INET6) {
43  _addr6 = (const sockaddr_in6 &)inaddr;
44 
45  } else {
46  nassert_raise("unsupported address family");
47  clear();
48  }
49 }
50 
51 /**
52  *
53  */
54 INLINE Socket_Address::
55 Socket_Address(const struct sockaddr_in &inaddr) :
56  _addr4(inaddr) {
57 }
58 
59 /**
60  *
61  */
62 INLINE Socket_Address::
63 Socket_Address(const struct sockaddr_in6 &inaddr) :
64  _addr6(inaddr) {
65 
66  if (IN6_IS_ADDR_V4MAPPED(&_addr6.sin6_addr) != 0) {
67  // This is really an IPv4 address disguised as an IPv6 address.
68  _addr4.sin_family = AF_INET;
69  _addr4.sin_addr.s_addr = ((uint32_t *)&_addr6.sin6_addr)[3];
70  }
71 }
72 
73 /**
74  *
75  */
76 INLINE Socket_Address::
77 Socket_Address(const struct sockaddr_storage &inaddr) :
78  _storage(inaddr) {
79 }
80 
81 /**
82  * Normal Destructor
83  */
84 INLINE Socket_Address::
86 }
87 
88 /**
89  *
90  */
91 INLINE bool Socket_Address::
92 operator == (const Socket_Address &in) const {
93  if (_storage.ss_family != in._storage.ss_family) {
94  return false;
95  }
96 
97  if (_storage.ss_family == AF_INET) {
98  return _addr4.sin_port == in._addr4.sin_port &&
99  _addr4.sin_addr.s_addr == in._addr4.sin_addr.s_addr;
100 
101  } else if (_storage.ss_family == AF_INET6) {
102  return _addr6.sin6_port != in._addr6.sin6_port &&
103  memcmp((char *) &_addr6.sin6_addr,
104  (char *) &in._addr6.sin6_addr,
105  sizeof(_addr6.sin6_addr)) == 0;
106  }
107 
108  // Unsupported address family.
109  nassert_raise("unsupported address family");
110  return false;
111 }
112 
113 /**
114  *
115  */
116 INLINE bool Socket_Address::
117 operator != (const Socket_Address &in) const {
118  return !operator ==(in);
119 }
120 
121 /**
122  * Set to the broadcast address and a specified port
123  */
124 INLINE bool Socket_Address::
125 set_broadcast(unsigned short port) {
126  _addr4.sin_family = AF_INET;
127  _addr4.sin_addr.s_addr = 0xffffffff;
128  _addr4.sin_port = htons(port);
129  return true;
130 }
131 
132 /**
133  * Set to any address and a specified port
134  */
135 INLINE bool Socket_Address::
136 set_any_IP(unsigned short port) {
137  _addr4.sin_family = AF_INET;
138  _addr4.sin_addr.s_addr = INADDR_ANY;
139  _addr4.sin_port = htons(port);
140  return true;
141 }
142 
143 /**
144  * Set to any IPv6 address and a specified port.
145  */
146 INLINE bool Socket_Address::
147 set_any_IPv6(unsigned short port) {
148  _addr6.sin6_family = AF_INET6;
149  _addr6.sin6_addr = in6addr_any;
150  _addr6.sin6_port = htons(port);
151  _addr6.sin6_scope_id = 0;
152  return true;
153 }
154 
155 /**
156  * Set to a specified port
157  */
158 INLINE bool Socket_Address::
159 set_port(unsigned short port) {
160  _addr4.sin_port = htons(port);
161  return true;
162 }
163 
164 /**
165  * Set the internal values to a suitable known value
166  */
167 INLINE void Socket_Address::
168 clear() {
169  _addr4.sin_family = AF_INET;
170  _addr4.sin_addr.s_addr = INADDR_ANY;
171  _addr4.sin_port = htons(0);
172 }
173 
174 /**
175  * Returns AF_INET if this is an IPv4 address, or AF_INET6 if this is an IPv6
176  * address.
177  */
178 INLINE sa_family_t Socket_Address::
179 get_family() const {
180  return _storage.ss_family;
181 }
182 
183 /**
184  * Get the port portion as an integer
185  */
186 INLINE unsigned short Socket_Address::
187 get_port() const {
188  return ntohs(_addr4.sin_port);
189 }
190 
191 /**
192  *
193  */
194 INLINE bool Socket_Address::
195 set_host(uint32_t in_hostname, unsigned short port) {
196  memcpy(&_addr4.sin_addr, &in_hostname, sizeof(in_hostname));
197  _addr4.sin_port = htons(port);
198  _addr4.sin_family = AF_INET;
199  return true;
200 }
201 
202 /**
203  *
204  */
205 INLINE bool Socket_Address::
206 operator < (const Socket_Address &in) const {
207  if (_storage.ss_family != in._storage.ss_family) {
208  return _storage.ss_family < in._storage.ss_family;
209  }
210 
211  if (_storage.ss_family == AF_INET) {
212  if (_addr4.sin_port != in._addr4.sin_port) {
213  return _addr4.sin_port < in._addr4.sin_port;
214  }
215 
216  return _addr4.sin_addr.s_addr < in._addr4.sin_addr.s_addr;
217 
218  } else if (_storage.ss_family == AF_INET6) {
219  if (_addr6.sin6_port != in._addr6.sin6_port) {
220  return _addr6.sin6_port < in._addr6.sin6_port;
221  }
222 
223  return IN6_ARE_ADDR_EQUAL(&_addr6.sin6_addr, &in._addr6.sin6_addr) != 0;
224  }
225 
226  // Unsupported address family.
227  nassert_raise("unsupported address family");
228  return false;
229 }
230 
231 /**
232  * True if the address is zero.
233  */
234 INLINE bool Socket_Address::
235 is_any() const {
236  if (_storage.ss_family == AF_INET) {
237  return (_addr4.sin_addr.s_addr == 0);
238 
239  } else if (_storage.ss_family == AF_INET6) {
240  return IN6_IS_ADDR_UNSPECIFIED(&_addr6.sin6_addr) != 0;
241 
242  } else {
243  return true;
244  }
245 }
246 
247 /**
248  * True if the address is in the multicast range.
249  */
250 INLINE bool Socket_Address::
251 is_mcast_range() const {
252  if (_storage.ss_family == AF_INET) {
253  uint32_t address = ntohl(_addr4.sin_addr.s_addr);
254  // 224.0.0.0-239.255.255.255 .. e0,ef
255  return (address >= 0xe0000000 && address < 0xefffffff);
256 
257  } else if (_storage.ss_family == AF_INET6) {
258  // ff00::/8
259  return IN6_IS_ADDR_MULTICAST(&_addr6.sin6_addr) != 0;
260 
261  } else {
262  return false;
263  }
264 }
virtual ~Socket_Address()
Normal Destructor.
bool is_any() const
True if the address is zero.
bool set_port(unsigned short port)
Set to a specified port.
bool set_any_IP(unsigned short port)
Set to any address and a specified port.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool set_broadcast(unsigned short port)
Set to the broadcast address and a specified port.
unsigned short get_port() const
Get the port portion as an integer.
bool set_any_IPv6(unsigned short port)
Set to any IPv6 address and a specified port.
sa_family_t get_family() const
Returns AF_INET if this is an IPv4 address, or AF_INET6 if this is an IPv6 address.
void clear()
Set the internal values to a suitable known value.
A simple place to store and manipulate tcp and port address for communication layer.
bool is_mcast_range() const
True if the address is in the multicast range.
bool set_host(const std::string &hostname, unsigned short port)
This function will take a port and string-based TCP address and initialize the address with this info...