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)) {
 
  488    while ((tmp = 
strsep(&list, 
","))) {
 
  490        int already_included = 0;
 
  497            if (!strcasecmp(
current->name, tmp)) { 
 
  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) {
 
 
  591    while ((tmp = 
strsep(&list, 
","))) {
 
  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.
char * strsep(char **str, const char *delims)
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]
#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 *attribute_pure 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::@191 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,...)