34 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__) 36 #include <net/route.h> 40 #include <sys/sockio.h> 42 #elif defined(HAVE_GETIFADDRS) 53 #if (!defined(SOLARIS) && !defined(HAVE_GETIFADDRS)) 59 static void score_address(
const struct sockaddr_in *sin,
struct in_addr *best_addr,
int *best_score)
67 if (address[0] ==
'0') {
70 }
else if (strncmp(address,
"127", 3) == 0) {
73 }
else if (strncmp(address,
"10.", 3) == 0) {
76 }
else if (strncmp(address,
"172", 3) == 0) {
78 if (address[4] ==
'1' && address[5] >=
'6' && address[6] ==
'.') {
81 }
else if (address[4] ==
'2' && address[6] ==
'.') {
84 }
else if (address[4] ==
'3' && (address[5] ==
'0' || address[5] ==
'1')) {
91 }
else if (strncmp(address,
"198.1", 5) == 0 && address[5] >=
'8' && address[6] ==
'.') {
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)))) {
279 struct ast_ha *start = original;
292 prev->
next = current;
319 struct ast_acl *current_cursor;
327 if (!(clone =
ast_calloc(1,
sizeof(*clone)))) {
328 ast_log(
LOG_ERROR,
"Failed to allocate ast_acl_list struct while cloning an ACL\n");
336 if ((
acl_new(¤t_clone, current_cursor->
name))) {
337 ast_log(
LOG_ERROR,
"Failed to allocate ast_acl struct while cloning an ACL.\n");
351 if (current_cursor->
acl && !current_clone->
acl) {
386 if (sscanf(mask_str,
"%30d", &mask) != 1) {
391 struct sockaddr_in sin;
392 if (mask < 0 || mask > 32) {
395 memset(&sin, 0,
sizeof(sin));
396 sin.sin_family = AF_INET;
402 sin.sin_addr.s_addr = htonl(0xFFFFFFFF << (32 - mask));
406 struct sockaddr_in6 sin6;
408 if (mask < 0 || mask > 128) {
411 memset(&sin6, 0,
sizeof(sin6));
412 sin6.sin6_family = AF_INET6;
413 for (i = 0; i < 4; ++i) {
419 V6_WORD(&sin6, i) = htonl(0xFFFFFFFF << (mask < 32 ? (32 - mask) : 0));
420 mask -= mask < 32 ? mask : 32;
423 memcpy(&addr->
ss, &sin6,
sizeof(sin6));
424 addr->
len =
sizeof(sin6);
454 working_list = *path;
459 if (strncasecmp(sense,
"a", 1)) {
489 while ((tmp =
strsep(&list,
","))) {
491 int already_included = 0;
498 if (!strcasecmp(current->
name, tmp)) {
500 ast_log(
LOG_ERROR,
"Named ACL '%s' occurs multiple times in ACL definition. " 501 "Please update your ACL configuration.\n", tmp);
505 already_included = 1;
510 if (already_included) {
530 if (named_acl_flag) {
592 while ((tmp =
strsep(&list,
","))) {
602 address =
strsep(&tmp,
"/");
609 if (*address ==
'!') {
613 ha->
sense = allowing;
635 "Converting to an IPv4 ACL network address.\n");
642 }
else if (strchr(mask,
':') || strchr(mask,
'.')) {
658 "Converting to an IPv4 ACL netmask.\n");
661 if (addr_is_v4 ^ mask_is_v4) {
688 ast_log(
LOG_WARNING,
"Unable to apply netmask %s to address %s\n", failmask, failaddr);
725 for (; ha; ha = ha->
next) {
747 for (; ha; ha = ha->
next) {
812 const struct ast_ha *current_ha;
814 for (current_ha = ha; current_ha; current_ha = current_ha->
next) {
820 char iabuf[INET_ADDRSTRLEN];
821 char iabuf2[INET_ADDRSTRLEN];
825 ast_debug(1,
"##### Testing %s with %s\n", iabuf, iabuf2);
832 ast_log(
LOG_ERROR,
"%s provided to ast_sockaddr_ipv4_mapped could not be converted. That shouldn't be possible.\n",
836 addr_to_use = &mapped_addr;
870 res = current_ha->
sense;
885 ast_debug(1,
"Multiple addresses. Using the first only\n");
905 snprintf(srv,
sizeof(srv),
"%s.%s", service, hostname);
906 if ((srv_ret =
ast_get_srv(
NULL, host,
sizeof(host), &tportno, srv)) > 0) {
957 if (sscanf(value,
"%30d", &fval) == 1) {
972 if (sscanf(value,
"%30i", &fval) == 1) {
977 for (x = 0; x <
ARRAY_LEN(dscp_pool1); x++) {
978 if (!strcasecmp(value, dscp_pool1[x].
name)) {
979 *tos = dscp_pool1[x].
space << 2;
991 for (x = 0; x <
ARRAY_LEN(dscp_pool1); x++) {
992 if (dscp_pool1[x].
space == (tos >> 2)) {
993 return dscp_pool1[x].
name;
1012 const char *sock_err;
1045 ast_debug(3,
"For destination '%s', our source address is '%s'.\n",
1061 ast_debug(3,
"Attached to given IP address\n");
1065 if (gethostname(ourhost,
sizeof(ourhost) - 1)) {
1074 ast_debug(3,
"Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
1092 for (; ha; ha = ha->
next, ++index) {
1105 ast_cli(fd,
"%sACL: %s%s\n---------------------------------------------\n",
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
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.
struct sockaddr_storage ss
#define AST_SOCKADDR_BUFLEN
void ast_acl_output(int fd, struct ast_acl_list *acl_list, const char *prefix)
output an ACL to the provided fd
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk locking-related definitions:
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
static const struct dscp_codepoint dscp_pool1[]
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
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.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
struct ast_acl::@218 list
static struct ast_ha * append_ha_core(const char *sense, const char *stuff, struct ast_ha *path, int *error, int port_flags)
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.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Support for DNS SRV records, used in to locate SIP services.
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.
char name[ACL_NAME_LENGTH]
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.
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl_list)
Free a list of ACLs.
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.
static char ourhost[MAXHOSTNAMELEN]
enum ast_cc_service_type service
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
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.
Wrapper for an ast_acl linked list.
static int parse_cidr_mask(struct ast_sockaddr *addr, int is_v4, const char *mask_str)
Parse a netmask in CIDR notation.
void ast_cli(int fd, const char *fmt,...)
Socket address structure.
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 resolve_first(struct ast_sockaddr *addr, const char *name, int flag, int family)
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
#define ast_strlen_zero(foo)
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
internal representation of ACL entries In principle user applications would have no need for this...
void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
Copy the contents of one HA to another.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
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.
General Asterisk PBX channel definitions.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
struct ast_sockaddr netmask
Access Control of various sorts.
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
static void score_address(const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
#define ast_strdupa(s)
duplicate a string in memory from the stack
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.
#define ast_malloc(len)
A wrapper for malloc()
an ast_acl is a linked list node of ast_ha structs which may have names.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
const char * ast_tos2str(unsigned int tos)
Convert a TOS value into its string representation.
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.
Wrapper for network related headers, masking differences between various operating systems...
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
void ast_ha_output(int fd, const struct ast_ha *ha, const char *prefix)
output an HA to the provided fd
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define ast_calloc(num, len)
A wrapper for calloc()
static int get_local_address(struct ast_sockaddr *ourip)
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
struct ast_ha * ast_named_acl_find(const char *name, int *is_realtime, int *is_undefined)
Retrieve a named ACL.
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
char * strsep(char **str, const char *delims)
struct ast_ha * ast_duplicate_ha_list(struct ast_ha *original)
Duplicate the contents of a list of host access rules.
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
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.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
static struct ast_str * hostname
int error(const char *format,...)
static enum ast_acl_sense ast_apply_acl_internal(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *log_prefix)
static int acl_new(struct ast_acl **pointer, const char *name)
static void debug_ha_sense_appended(struct ast_ha *ha)
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
static struct ast_ha * ast_duplicate_ha(struct ast_ha *original)
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.
#define DEBUG_ATLEAST(level)
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
struct ast_sockaddr bindaddr
#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.
static char prefix[MAX_PREFIX]