1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
|
/** @file
A brief file description
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if !defined (_ink_inet_h_)
#define _ink_inet_h_
#include "ink_platform.h"
#include "ink_port.h"
#include "ink_apidefs.h"
#define INK_GETHOSTBYNAME_R_DATA_SIZE 1024
#define INK_GETHOSTBYADDR_R_DATA_SIZE 1024
struct ink_gethostbyname_r_data
{
int herrno;
struct hostent ent;
char buf[INK_GETHOSTBYNAME_R_DATA_SIZE];
};
struct ink_gethostbyaddr_r_data
{
int herrno;
struct hostent ent;
char buf[INK_GETHOSTBYADDR_R_DATA_SIZE];
};
/**
returns the IP address of the hostname. If the hostname has
multiple IP addresses, the first IP address in the list returned
by 'gethostbyname' is returned.
@note Not thread-safe
*/
unsigned int host_to_ip(char *hostname);
/**
Wrapper for gethostbyname_r(). If successful, returns a pointer
to the hostent structure. Returns NULL and sets data->herrno to
the appropriate error code on failure.
@param hostname null-terminated host name string
@param data pointer to ink_gethostbyname_r_data allocated by the caller
*/
struct hostent *ink_gethostbyname_r(char *hostname, ink_gethostbyname_r_data * data);
/**
Wrapper for gethostbyaddr_r(). If successful, returns a pointer
to the hostent structure. Returns NULL and sets data->herrno to
the appropriate error code on failure.
@param ip IP address of the host
@param len length of the buffer indicated by ip
@param type family of the address
@param data pointer to ink_gethostbyname_r_data allocated by the caller
*/
struct hostent *ink_gethostbyaddr_r(char *ip, int len, int type, ink_gethostbyaddr_r_data * data);
/**
Wrapper for inet_addr().
@param s IP address in the Internet standard dot notation.
*/
inkcoreapi uint32_t ink_inet_addr(const char *s);
const char *ink_inet_ntop(const struct sockaddr *addr, char *dst, size_t size);
uint16_t ink_inet_port(const struct sockaddr *addr);
/// Reset an address to invalid.
/// Convenience overload.
/// @note Useful for marking a member as not yet set.
inline void ink_inet_invalidate(sockaddr_storage* addr) {
addr->ss_family = AF_UNSPEC;
}
/// Set to all zero.
inline void ink_inet_init(sockaddr_storage* addr) {
memset(addr, 0, sizeof(addr));
ink_inet_invalidate(addr);
}
/// @return @a a cast to @c sockaddr_storage*.
inline sockaddr_storage* ink_inet_ss_cast(sockaddr* a) {
return static_cast<sockaddr_storage*>(static_cast<void*>(a));
}
/// @return @a a cast to @c sockaddr_storage const*.
inline sockaddr_storage const* ink_inet_ss_cast(sockaddr const* a) {
return static_cast<sockaddr_storage const*>(static_cast<void const*>(a));
}
/// @return @a a cast to @c sockaddr_storage const*.
inline sockaddr_storage* ink_inet_ss_cast(sockaddr_in6* a) {
return reinterpret_cast<sockaddr_storage*>(a);
}
/// @return @a a cast to @c sockaddr_storage const*.
inline sockaddr_storage const* ink_inet_ss_cast(sockaddr_in6 const* a) {
return reinterpret_cast<sockaddr_storage const*>(a);
}
/// @return @a a cast to @c sockaddr*.
inline sockaddr* ink_inet_sa_cast(sockaddr_storage* a) {
return reinterpret_cast<sockaddr*>(a);
}
/// @return @a a cast to sockaddr const*.
inline sockaddr const* ink_inet_sa_cast(sockaddr_storage const* a) {
return reinterpret_cast<sockaddr const*>(a);
}
/// @return @a a cast to sockaddr const*.
inline sockaddr const* ink_inet_sa_cast(sockaddr_in6 const* a) {
return reinterpret_cast<sockaddr const*>(a);
}
/// Test for IPv4 protocol.
/// @return @c true if the address is IPv4, @c false otherwise.
inline bool ink_inet_is_ip4(sockaddr_storage const* addr) {
return AF_INET == addr->ss_family;
}
/// Test for IPv4 protocol.
/// @return @c true if the address is IPv4, @c false otherwise.
inline bool ink_inet_is_ip4(sockaddr const* addr) {
return AF_INET == addr->sa_family;
}
/// Test for IPv6 protocol.
/// Convenience overload.
/// @return @c true if the address is IPv6, @c false otherwise.
inline bool ink_inet_is_ip6(sockaddr_storage const* addr) {
return AF_INET6 == addr->ss_family;
}
/// IPv4 cast.
/// @return @a a cast to a @c sockaddr_in*
inline sockaddr_in* ink_inet_ip4_cast(
sockaddr_storage* a ///< Address structure.
) {
return static_cast<sockaddr_in*>(static_cast<void*>(a));
}
/// IPv4 cast.
/// @return @a a cast to a @c sockaddr_in*
inline sockaddr_in const* ink_inet_ip4_cast(
sockaddr_storage const* a ///< Address structure.
) {
return static_cast<sockaddr_in const*>(static_cast<void const*>(a));
}
/// IPv4 cast.
/// @return @a a cast to a @c sockaddr_in*
inline sockaddr_in const* ink_inet_ip4_cast(
sockaddr const* a ///< Address structure.
) {
return reinterpret_cast<sockaddr_in const*>(a);
}
/// IPv6 cast.
/// @return @a a cast to a @c sockaddr_in6*
inline sockaddr_in6* ink_inet_ip6_cast(sockaddr_storage* a) {
return static_cast<sockaddr_in6*>(static_cast<void*>(a));
}
/// IPv6 cast.
/// @return @a a cast to a @c sockaddr_in6*
inline sockaddr_in6 const* ink_inet_ip6_cast(sockaddr_storage const* a) {
return static_cast<sockaddr_in6 const*>(static_cast<void const*>(a));
}
/** Get a reference to the port in an address.
@note Because this is direct access, the port value is in network order.
@see ink_inet_get_port for host order copy.
@return A reference to the port value in an IPv4 or IPv6 address.
@internal This is primarily for internal use but it might be handy for
clients so it is exposed.
*/
inline uint16_t& ink_inet_port_cast(sockaddr_storage* ss) {
static uint16_t dummy = 0;
return AF_INET == ss->ss_family
? ink_inet_ip4_cast(ss)->sin_port
: AF_INET6 == ss->ss_family
? ink_inet_ip6_cast(ss)->sin6_port
: (dummy = 0)
;
}
/** Get a reference to the port in an address.
@note Because this is direct access, the port value is in network order.
@see ink_inet_get_port for host order copy.
@return A reference to the port value in an IPv4 or IPv6 address.
@internal This is primarily for internal use but it might be handy for
clients so it is exposed.
*/
inline uint16_t const& ink_inet_port_cast(sockaddr_storage const* ss) {
return ink_inet_port_cast(const_cast<sockaddr_storage*>(ss));
}
/** Get a reference to the port in an address.
@note Because this is direct access, the port value is in network order.
@see ink_inet_get_port for host order copy.
@return A reference to the port value in an IPv4 or IPv6 address.
@internal This is primarily for internal use but it might be handy for
clients so it is exposed.
*/
inline uint16_t const& ink_inet_port_cast(sockaddr const* sa) {
return ink_inet_port_cast(ink_inet_ss_cast(sa));
}
/** Access the IPv4 address.
If @a addr is not IPv4 the results are indeterminate.
@note This is direct access to the address so it will be in
network order.
@return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t& ink_inet_ip4_addr_cast(sockaddr_storage* addr) {
return ink_inet_ip4_cast(addr)->sin_addr.s_addr;
}
/** Access the IPv4 address.
If @a addr is not IPv4 the results are indeterminate.
@note This is direct access to the address so it will be in
network order.
@return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t const& ink_inet_ip4_addr_cast(sockaddr_storage const* addr) {
return ink_inet_ip4_cast(addr)->sin_addr.s_addr;
}
/** Access the IPv4 address.
If @a addr is not IPv4 the results are indeterminate.
@note This is direct access to the address so it will be in
network order.
@return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t const& ink_inet_ip4_addr_cast(sockaddr const* addr) {
return ink_inet_ip4_cast(addr)->sin_addr.s_addr;
}
/// Write IPv4 data to a @c sockaddr_storage.
inline void ink_inet_ip4_set(
sockaddr_storage* ss, ///< Destination storage.
in_addr_t ip4, ///< address, IPv4 network order.
uint16_t port = 0 ///< port, network order.
) {
sockaddr_in* sin = ink_inet_ip4_cast(ss);
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
memcpy(&(sin->sin_addr), &ip4, sizeof(ip4));
sin->sin_port = port;
}
#endif // _ink_inet.h
|