34#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__)
40#include <sys/sockio.h>
42#elif defined(HAVE_GETIFADDRS)
53#if (!defined(SOLARIS) && !defined(HAVE_GETIFADDRS))
59static void score_address(
const struct sockaddr_in *sin,
struct in_addr *best_addr,
int *best_score)
70 }
else if (strncmp(
address,
"127", 3) == 0) {
73 }
else if (strncmp(
address,
"10.", 3) == 0) {
76 }
else if (strncmp(
address,
"172", 3) == 0) {
94 }
else if (strncmp(
address,
"192.168", 7) == 0) {
97 }
else if (strncmp(
address,
"169.254", 7) == 0) {
105 }
else if (strncmp(
address,
"192.0.2.", 8) == 0) {
112 if (score > *best_score) {
114 memcpy(best_addr, &sin->sin_addr,
sizeof(*best_addr));
122 struct lifreq *ifr =
NULL;
125 struct sockaddr_in *sa;
129#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) || defined(__GLIBC__)
130 struct ifaddrs *ifap, *ifaphead;
132 const struct sockaddr_in *sin;
134 struct in_addr best_addr;
135 int best_score = -100;
136 memset(&best_addr, 0,
sizeof(best_addr));
138#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) || defined(__GLIBC__)
139 rtnerr = getifaddrs(&ifaphead);
146 s = socket(AF_INET, SOCK_STREAM, 0);
149#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) || defined(__GLIBC__)
150 for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
152 if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET) {
153 sin = (
const struct sockaddr_in *) ifap->ifa_addr;
157 if (best_score == 0) {
167 ifn.lifn_family = AF_INET;
170 if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
175 bufsz = ifn.lifn_count *
sizeof(
struct lifreq);
180 memset(
buf, 0, bufsz);
183 ifc.lifc_len = bufsz;
185 ifc.lifc_family = AF_INET;
187 if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
193 for (ifr = ifc.lifc_req, x = 0; x < ifn.lifn_count; ifr++, x++) {
194 sa = (
struct sockaddr_in *)&(ifr->lifr_addr);
198 if (best_score == 0) {
208#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
209 freeifaddrs(ifaphead);
212 if (res == 0 && ourip) {
214 ourip->
ss.ss_family = AF_INET;
215 ((
struct sockaddr_in *)&ourip->
ss)->sin_addr = best_addr;
267 if ((new_ha =
ast_calloc(1,
sizeof(*new_ha)))) {
278 struct ast_ha *start = original;
318 struct ast_acl *current_cursor;
326 if (!(clone =
ast_calloc(1,
sizeof(*clone)))) {
327 ast_log(
LOG_ERROR,
"Failed to allocate ast_acl_list struct while cloning an ACL\n");
335 if ((
acl_new(¤t_clone, current_cursor->
name))) {
336 ast_log(
LOG_ERROR,
"Failed to allocate ast_acl struct while cloning an ACL.\n");
350 if (current_cursor->
acl && !current_clone->
acl) {
385 if (sscanf(mask_str,
"%30d", &mask) != 1) {
390 struct sockaddr_in sin;
391 if (mask < 0 || mask > 32) {
394 memset(&sin, 0,
sizeof(sin));
395 sin.sin_family = AF_INET;
401 sin.sin_addr.s_addr = htonl(0xFFFFFFFF << (32 - mask));
405 struct sockaddr_in6 sin6;
407 if (mask < 0 || mask > 128) {
410 memset(&sin6, 0,
sizeof(sin6));
411 sin6.sin6_family = AF_INET6;
412 for (i = 0; i < 4; ++i) {
418 V6_WORD(&sin6, i) = htonl(0xFFFFFFFF << (mask < 32 ? (32 - mask) : 0));
419 mask -= mask < 32 ? mask : 32;
422 memcpy(&addr->
ss, &sin6,
sizeof(sin6));
423 addr->
len =
sizeof(sin6);
453 working_list = *path;
458 if (strncasecmp(sense,
"a", 1)) {
490 int already_included = 0;
499 ast_log(
LOG_ERROR,
"Named ACL '%s' occurs multiple times in ACL definition. "
500 "Please update your ACL configuration.\n",
tmp);
504 already_included = 1;
509 if (already_included) {
529 if (named_acl_flag) {
612 ha->
sense = allowing;
634 "Converting to an IPv4 ACL network address.\n");
641 }
else if (strchr(mask,
':') || strchr(mask,
'.')) {
657 "Converting to an IPv4 ACL netmask.\n");
660 if (addr_is_v4 ^ mask_is_v4) {
687 ast_log(
LOG_WARNING,
"Unable to apply netmask %s to address %s\n", failmask, failaddr);
724 for (; ha; ha = ha->
next) {
746 for (; ha; ha = ha->
next) {
769 if (
acl->is_invalid) {
811 const struct ast_ha *current_ha;
813 for (current_ha = ha; current_ha; current_ha = current_ha->
next) {
819 char iabuf[INET_ADDRSTRLEN];
820 char iabuf2[INET_ADDRSTRLEN];
824 ast_debug(1,
"##### Testing %s with %s\n", iabuf, iabuf2);
831 ast_log(
LOG_ERROR,
"%s provided to ast_sockaddr_ipv4_mapped could not be converted. That shouldn't be possible.\n",
835 addr_to_use = &mapped_addr;
869 res = current_ha->
sense;
888 for (i = 0; i < addrs_cnt; i++) {
890 resolved = &addrs[i];
894 }
else if (addrs_cnt > 1) {
895 ast_debug(1,
"Multiple addresses. Using the first only\n");
917 if ((srv_ret =
ast_get_srv(
NULL, host,
sizeof(host), &tportno, srv)) > 0) {
973 if (sscanf(
value,
"%30d", &fval) == 1) {
988 if (sscanf(
value,
"%30i", &fval) == 1) {
1028 const char *sock_err;
1061 ast_debug(3,
"For destination '%s', our source address is '%s'.\n",
1077 ast_debug(3,
"Attached to given IP address\n");
1081 if (gethostname(ourhost,
sizeof(ourhost) - 1)) {
1090 ast_debug(3,
"Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
1108 for (; ha; ha = ha->
next, ++index) {
1121 ast_cli(fd,
"%sACL: %s%s\n---------------------------------------------\n",
1123 acl->is_realtime ?
" (realtime)" :
"");
static const struct dscp_codepoint dscp_pool1[]
static int resolve_match_or_first(struct ast_sockaddr *addr, const char *name, int flag, int family, struct ast_sockaddr *preference)
static struct ast_ha * append_ha_core(const char *sense, const char *stuff, struct ast_ha *path, int *error, int port_flags)
static int acl_new(struct ast_acl **pointer, const char *name)
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
static int parse_cidr_mask(struct ast_sockaddr *addr, int is_v4, const char *mask_str)
Parse a netmask in CIDR notation.
void ast_ha_output(int fd, const struct ast_ha *ha, const char *prefix)
output an HA to the provided fd
struct ast_ha * ast_duplicate_ha_list(struct ast_ha *original)
Duplicate the contents of a list of host access rules.
void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
Copy the contents of one HA to another.
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
int ast_get_ip_or_srv_with_preference(struct ast_sockaddr *addr, const char *hostname, const char *service, struct ast_sockaddr *preference)
Get the IP address given a hostname and optional service with a preferred result.
enum ast_acl_sense ast_apply_acl_nolog(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address, don't log failure.
const char * ast_tos2str(unsigned int tos)
Convert a TOS value into its string representation.
static int get_local_address(struct ast_sockaddr *ourip)
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl_list)
Free a list of ACLs.
static void debug_ha_sense_appended(struct ast_ha *ha)
enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
static void score_address(const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value.
struct ast_ha * ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule with optional port to a list of HAs.
static struct ast_ha * ast_duplicate_ha(struct ast_ha *original)
void ast_acl_output(int fd, struct ast_acl_list *acl_list, const char *prefix)
output an ACL to the provided fd
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
struct ast_acl_list * ast_duplicate_acl_list(struct ast_acl_list *original)
Duplicates the contests of a list of lists of host access rules.
static enum ast_acl_sense ast_apply_acl_internal(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *log_prefix)
void ast_ha_join_cidr(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value using CIDR notation.
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
Access Control of various sorts.
struct ast_ha * ast_named_acl_find(const char *name, int *is_realtime, int *is_undefined)
Retrieve a named ACL.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
enum ast_cc_service_type service
struct ast_sockaddr bindaddr
General Asterisk PBX channel definitions.
Standard Command Line Interface.
void ast_cli(int fd, const char *fmt,...)
static char prefix[MAX_PREFIX]
char * strsep(char **str, const char *delims)
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Asterisk locking-related definitions:
static char hostname[MAXHOSTNAMELEN]
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
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.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
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.
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
#define V6_WORD(sin6, index)
Isolate a 32-bit section of an IPv6 address.
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.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
#define AST_SOCKADDR_BUFLEN
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Wrapper for network related headers, masking differences between various operating systems....
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Support for DNS SRV records, used in to locate SIP services.
int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Wrapper for an ast_acl linked list.
an ast_acl is a linked list node of ast_ha structs which may have names.
struct ast_acl::@180 list
char name[ACL_NAME_LENGTH]
internal representation of ACL entries In principle user applications would have no need for this,...
struct ast_sockaddr netmask
Socket address structure.
struct sockaddr_storage ss
Support for dynamic strings.
int error(const char *format,...)