39 const struct sockaddr_in6 *sin6;
40 struct sockaddr_in sin4;
50 sin6 = (
const struct sockaddr_in6*)&addr->
ss;
52 memset(&sin4, 0,
sizeof(sin4));
53 sin4.sin_family = AF_INET;
54 sin4.sin_port = sin6->sin6_port;
55 sin4.sin_addr.s_addr = ((uint32_t *)&sin6->sin6_addr)[3];
69 char host[NI_MAXHOST];
70 char port[NI_MAXSERV];
73 static const size_t size =
sizeof(
host) - 1 +
sizeof(port) - 1 + 4;
90 if ((e = getnameinfo((
struct sockaddr *)&sa_tmp->
ss, sa_tmp->
len,
95 NI_NUMERICHOST | NI_NUMERICSERV))) {
110 "[%s]:%s" :
"%s:%s", host, port);
117 sa_tmp->
ss.ss_family == AF_INET6 ?
"[%s]" :
"%s", host);
151 addr = ((
struct sockaddr *)&sa_tmp->
ss)->sa_data;
153 for (i = 0; i < bytes ; ++i) {
154 for (j = 0; j < 8; ++j) {
155 if ((addr[i] >> j) & 1) {
167 char *orig_str =
str;
168 char *host_end =
NULL;
170 ast_debug(5,
"Splitting '%s' into...\n", str);
175 for (; *s && *s !=
']'; ++s) {
224 ast_debug(5,
"...host '%s' and port '%s'.\n", *host, *port ? *port :
"");
232 struct addrinfo hints;
233 struct addrinfo *res;
244 memset(&hints, 0,
sizeof(hints));
246 hints.ai_socktype = SOCK_DGRAM;
248 #ifdef AI_NUMERICSERV 249 hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
251 hints.ai_flags = AI_NUMERICHOST;
253 if ((e = getaddrinfo(host, port, &hints, &res))) {
254 if (e != EAI_NONAME) {
256 host,
S_OR(port,
"(null)"), gai_strerror(e));
265 if (res->ai_next !=
NULL) {
267 "addresses. Ignoring all but the first.\n");
271 addr->
len = res->ai_addrlen;
272 memcpy(&addr->
ss, res->ai_addr, addr->
len);
281 int flags,
int family)
283 struct addrinfo hints, *res, *ai;
284 char *s, *
host, *port;
298 memset(&hints, 0,
sizeof(hints));
299 hints.ai_family = family;
300 hints.ai_socktype = SOCK_DGRAM;
302 if ((e = getaddrinfo(host, port, &hints, &res))) {
304 host,
S_OR(port,
"(null)"), gai_strerror(e));
310 for (ai = res; ai; ai = ai->ai_next) {
325 for (ai = res; ai; ai = ai->ai_next) {
326 (*addrs)[i].len = ai->ai_addrlen;
327 memcpy(&(*addrs)[i].ss, ai->ai_addr, ai->ai_addrlen);
338 const char*
name,
int flag,
int family)
344 if (addrs_cnt <= 0) {
348 ast_debug(1,
"Multiple addresses resolving %s, using the first one only\n", name);
363 struct sockaddr_in result4 = { 0, };
364 struct sockaddr_in *addr4 = (
struct sockaddr_in *) &addr->
ss;
365 struct sockaddr_in *mask4 = (
struct sockaddr_in *) &netmask->
ss;
366 result4.sin_family = AF_INET;
367 result4.sin_addr.s_addr = addr4->sin_addr.s_addr & mask4->sin_addr.s_addr;
370 struct sockaddr_in6 result6 = { 0, };
371 struct sockaddr_in6 *addr6 = (
struct sockaddr_in6 *) &addr->
ss;
372 struct sockaddr_in6 *mask6 = (
struct sockaddr_in6 *) &netmask->
ss;
374 result6.sin6_family = AF_INET6;
375 for (i = 0; i < 4; ++i) {
378 memcpy(&result->
ss, &result6,
sizeof(result6));
379 result->
len =
sizeof(result6);
396 if (a_tmp->len != b_tmp->
len) {
398 a_tmp = &ipv4_mapped;
400 b_tmp = &ipv4_mapped;
404 if (a_tmp->len < b_tmp->
len) {
406 }
else if (a_tmp->len > b_tmp->
len) {
410 return memcmp(&a_tmp->ss, &b_tmp->
ss, a_tmp->len);
417 const struct in_addr *ip4a, *ip4b;
418 const struct in6_addr *ip6a, *ip6b;
424 if (a_tmp->
len != b_tmp->
len) {
426 a_tmp = &ipv4_mapped;
428 b_tmp = &ipv4_mapped;
434 }
else if (a->
len > b->
len) {
438 switch (a_tmp->
ss.ss_family) {
440 ip4a = &((
const struct sockaddr_in*)&a_tmp->
ss)->sin_addr;
441 ip4b = &((
const struct sockaddr_in*)&b_tmp->
ss)->sin_addr;
442 ret = memcmp(ip4a, ip4b,
sizeof(*ip4a));
445 ip6a = &((
const struct sockaddr_in6*)&a_tmp->
ss)->sin6_addr;
446 ip6b = &((
const struct sockaddr_in6*)&b_tmp->
ss)->sin6_addr;
447 ret = memcmp(ip6a, ip6b,
sizeof(*ip6a));
459 if (addr->
len ==
sizeof(
struct sockaddr_in)
460 && addr->
ss.ss_family == AF_INET) {
461 return ntohs(((
struct sockaddr_in *)&addr->
ss)->sin_port);
463 if (addr->
len ==
sizeof(
struct sockaddr_in6)
464 && addr->
ss.ss_family == AF_INET6) {
465 return ntohs(((
struct sockaddr_in6 *)&addr->
ss)->sin6_port);
468 ast_log(
__LOG_DEBUG, file, line, func,
"Not an IPv4 nor IPv6 address, cannot get port.\n");
479 if (addr->
len ==
sizeof(
struct sockaddr_in)
480 && addr->
ss.ss_family == AF_INET) {
481 ((
struct sockaddr_in *)&addr->
ss)->sin_port = htons(port);
482 }
else if (addr->
len ==
sizeof(
struct sockaddr_in6)
483 && addr->
ss.ss_family == AF_INET6) {
484 ((
struct sockaddr_in6 *)&addr->
ss)->sin6_port = htons(port);
487 "Not an IPv4 nor IPv6 address, cannot set port.\n");
493 const struct sockaddr_in *sin = (
struct sockaddr_in *)&addr->
ss;
494 return ntohl(sin->sin_addr.s_addr);
503 return addr->
len ==
sizeof(
struct sockaddr_in)
504 && addr->
ss.ss_family == AF_INET;
509 const struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)&addr->
ss;
510 return addr->
len && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr);
520 const struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)&addr->
ss;
530 return addr->
len ==
sizeof(
struct sockaddr_in6)
531 && addr->
ss.ss_family == AF_INET6;
537 struct sockaddr_storage ss;
538 struct sockaddr_in sin;
539 struct sockaddr_in6 sin6;
554 switch (addr->
ss.ss_family) {
556 return ((
const struct sockaddr_in *)&addr->
ss)->sin_addr.s_addr;
558 return ((uint32_t *)&((
const struct sockaddr_in6 *)&addr->
ss)->sin6_addr)[3];
586 addr->
len =
sizeof(addr->
ss);
587 return accept(sockfd, (
struct sockaddr *)&addr->
ss, &addr->
len);
592 return bind(sockfd, (
const struct sockaddr *)&addr->
ss, addr->
len);
597 return connect(sockfd, (
const struct sockaddr *)&addr->
ss, addr->
len);
602 addr->
len =
sizeof(addr->
ss);
603 return getsockname(sockfd, (
struct sockaddr *)&addr->
ss, &addr->
len);
609 src_addr->
len =
sizeof(src_addr->
ss);
610 return recvfrom(sockfd, buf, len, flags,
611 (
struct sockaddr *)&src_addr->
ss, &src_addr->
len);
617 return sendto(sockfd, buf, len, flags,
618 (
const struct sockaddr *)&dest_addr->
ss, dest_addr->
len);
635 if ((res = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos,
sizeof(tos)))) {
637 "root privileges): %s\n", desc, tos, strerror(
errno));
639 ast_verb(2,
"Using %s TOS bits %d\n", desc, tos);
643 #if defined(IPV6_TCLASS) && defined(IPPROTO_IPV6) 646 if ((res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, &tos,
sizeof(tos)))) {
648 "root privileges): %s\n", desc, tos, strerror(
errno));
650 ast_verb(2,
"Using %s TOS bits %d in TCLASS field.\n", desc, tos);
657 if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &cos,
sizeof(cos))) {
661 ast_verb(2,
"Using %s CoS mark %d\n", desc, cos);
669 struct sockaddr_in *sin,
const char *
file,
int line,
const char *func)
672 memset(sin, 0,
sizeof(*sin));
676 if (addr->
len !=
sizeof(*sin)) {
685 *sin = *(
struct sockaddr_in *)&addr->
ss;
690 const char *
file,
int line,
const char *func)
692 memcpy(&addr->
ss, sin,
sizeof(*sin));
698 addr->
len =
sizeof(*sin);
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
struct sockaddr_storage ss
Asterisk main include file. File version handling, generic pbx functions.
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
const char * ast_transport2str(enum ast_transport transport)
Returns a string representation of an ast_transport.
uint32_t ast_sockaddr_ipv4(const struct ast_sockaddr *addr)
Get an IPv4 address of an ast_sockaddr.
int ast_sockaddr_ipv4_mapped(const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
Convert an IPv4-mapped IPv6 address into an IPv4 address.
int ast_sockaddr_is_ipv4_multicast(const struct ast_sockaddr *addr)
Determine if an IPv4 address is a multicast address.
int ast_accept(int sockfd, struct ast_sockaddr *addr)
Wrapper around accept(2) that uses struct ast_sockaddr.
Definitions to aid in the use of thread local storage.
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Socket address structure.
#define ast_verb(level,...)
#define AST_SOCKADDR_STR_DEFAULT
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
uint16_t _ast_sockaddr_port(const struct ast_sockaddr *addr, const char *file, int line, const char *func)
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Configuration File Parser.
int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, struct ast_sockaddr *result)
Apply a netmask to an address and store the result in a separate structure.
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
int ast_sockaddr_is_ipv6_link_local(const struct ast_sockaddr *addr)
Determine if this is a link-local IPv6 address.
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_malloc(len)
A wrapper for malloc()
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
#define AST_SOCKADDR_STR_PORT
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
void _ast_sockaddr_from_sin(struct ast_sockaddr *addr, const struct sockaddr_in *sin, const char *file, int line, const char *func)
#define AST_SOCKADDR_STR_HOST
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *sa, int format)
Convert a socket address to a string.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int _ast_sockaddr_to_sin(const struct ast_sockaddr *addr, struct sockaddr_in *sin, const char *file, int line, const char *func)
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
static void * cleanup(void *unused)
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
#define AST_SOCKADDR_STR_ADDR
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
void _ast_sockaddr_set_port(struct ast_sockaddr *addr, uint16_t port, const char *file, int line, const char *func)
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
#define AST_SOCKADDR_STR_FORMAT_MASK
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Pulls first resolved address and returns it.
#define DEBUG_ATLEAST(level)
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
static snd_pcm_format_t format
static struct ast_threadstorage ast_sockaddr_stringify_buf
#define V6_WORD(sin6, index)
Isolate a 32-bit section of an IPv6 address.
#define AST_SOCKADDR_STR_REMOTE