34 #include "asterisk/network.h"
36 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__)
38 #include <net/route.h>
42 #include <sys/sockio.h>
44 #elif defined(HAVE_GETIFADDRS)
54 #if (!defined(SOLARIS) && !defined(HAVE_GETIFADDRS))
60 static void score_address(
const struct sockaddr_in *sin,
struct in_addr *best_addr,
int *best_score)
68 if (address[0] ==
'0') {
71 }
else if (strncmp(address,
"127", 3) == 0) {
74 }
else if (strncmp(address,
"10.", 3) == 0) {
77 }
else if (strncmp(address,
"172", 3) == 0) {
79 if (address[4] ==
'1' && address[5] >=
'6' && address[6] ==
'.') {
82 }
else if (address[4] ==
'2' && address[6] ==
'.') {
85 }
else if (address[4] ==
'3' && (address[5] ==
'0' || address[5] ==
'1')) {
92 }
else if (strncmp(address,
"198.1", 5) == 0 && address[5] >=
'8' && address[6] ==
'.') {
95 }
else if (strncmp(address,
"192.168", 7) == 0) {
98 }
else if (strncmp(address,
"169.254", 7) == 0) {
106 }
else if (strncmp(address,
"192.0.2.", 8) == 0) {
113 if (score > *best_score) {
115 memcpy(best_addr, &sin->sin_addr,
sizeof(*best_addr));
123 struct lifreq *ifr = NULL;
126 struct sockaddr_in *sa;
130 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
131 struct ifaddrs *ifap, *ifaphead;
133 const struct sockaddr_in *sin;
135 struct in_addr best_addr;
136 int best_score = -100;
137 memset(&best_addr, 0,
sizeof(best_addr));
139 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
140 rtnerr = getifaddrs(&ifaphead);
147 s = socket(AF_INET, SOCK_STREAM, 0);
150 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
151 for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
153 if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET) {
154 sin = (
const struct sockaddr_in *) ifap->ifa_addr;
158 if (best_score == 0) {
168 ifn.lifn_family = AF_INET;
171 if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
176 bufsz = ifn.lifn_count *
sizeof(
struct lifreq);
177 if (!(buf =
malloc(bufsz))) {
181 memset(buf, 0, bufsz);
184 ifc.lifc_len = bufsz;
186 ifc.lifc_family = AF_INET;
188 if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
194 for (ifr = ifc.lifc_req, x = 0; x < ifn.lifn_count; ifr++, x++) {
195 sa = (
struct sockaddr_in *)&(ifr->lifr_addr);
199 if (best_score == 0) {
209 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
210 freeifaddrs(ifaphead);
213 if (res == 0 && ourip) {
215 ourip->
ss.ss_family = AF_INET;
216 ((
struct sockaddr_in *)&ourip->
ss)->sin_addr = best_addr;
246 if ((new_ha =
ast_calloc(1,
sizeof(*new_ha)))) {
258 struct ast_ha *start = original;
259 struct ast_ha *ret = NULL;
260 struct ast_ha *current, *prev = NULL;
265 prev->
next = current;
288 #define V6_WORD(sin6, index) ((uint32_t *)&((sin6)->sin6_addr))[(index)]
310 struct sockaddr_in result4 = { 0, };
311 struct sockaddr_in *addr4 = (
struct sockaddr_in *) &addr->
ss;
312 struct sockaddr_in *mask4 = (
struct sockaddr_in *) &netmask->
ss;
313 result4.sin_family = AF_INET;
314 result4.sin_addr.s_addr = addr4->sin_addr.s_addr & mask4->sin_addr.s_addr;
317 struct sockaddr_in6 result6 = { 0, };
318 struct sockaddr_in6 *addr6 = (
struct sockaddr_in6 *) &addr->
ss;
319 struct sockaddr_in6 *mask6 = (
struct sockaddr_in6 *) &netmask->
ss;
321 result6.sin6_family = AF_INET6;
322 for (i = 0; i < 4; ++i) {
325 memcpy(&result->
ss, &result6,
sizeof(result6));
326 result->
len =
sizeof(result6);
355 if (sscanf(mask_str,
"%30d", &mask) != 1) {
360 struct sockaddr_in sin;
361 if (mask < 0 || mask > 32) {
364 memset(&sin, 0,
sizeof(sin));
365 sin.sin_family = AF_INET;
371 sin.sin_addr.s_addr = htonl(0xFFFFFFFF << (32 - mask));
375 struct sockaddr_in6 sin6;
377 if (mask < 0 || mask > 128) {
380 memset(&sin6, 0,
sizeof(sin6));
381 sin6.sin6_family = AF_INET6;
382 for (i = 0; i < 4; ++i) {
388 V6_WORD(&sin6, i) = htonl(0xFFFFFFFF << (mask < 32 ? (32 - mask) : 0));
389 mask -= mask < 32 ? mask : 32;
392 memcpy(&addr->
ss, &sin6,
sizeof(sin6));
393 addr->
len =
sizeof(sin6);
402 struct ast_ha *prev = NULL;
405 char *address = NULL, *mask = NULL;
421 address =
strsep(&tmp,
"/");
442 "Converting to an IPv4 ACL network address.\n");
449 }
else if (strchr(mask,
':') || strchr(mask,
'.')) {
465 "Converting to an IPv4 ACL netmask.\n");
468 if (addr_is_v4 ^ mask_is_v4) {
491 ast_log(
LOG_WARNING,
"Unable to apply netmask %s to address %s\n", failmask, failaddr);
512 ast_debug(1,
"%s/%s sense %d appended to acl for peer\n", addr, mask, ha->
sense);
522 const struct ast_ha *current_ha;
524 for (current_ha = ha; current_ha; current_ha = current_ha->
next) {
529 char iabuf[INET_ADDRSTRLEN];
530 char iabuf2[INET_ADDRSTRLEN];
534 ast_debug(1,
"##### Testing %s with %s\n", iabuf, iabuf2);
541 ast_log(
LOG_ERROR,
"%s provided to ast_sockaddr_ipv4_mapped could not be converted. That shouldn't be possible.\n",
545 addr_to_use = &mapped_addr;
570 res = current_ha->
sense;
585 ast_debug(1,
"Multiple addresses. Using the first only\n");
605 snprintf(srv,
sizeof(srv),
"%s.%s", service, hostname);
606 if ((srv_ret =
ast_get_srv(NULL, host,
sizeof(host), &tportno, srv)) > 0) {
657 if (sscanf(value,
"%30d", &fval) == 1) {
672 if (sscanf(value,
"%30i", &fval) == 1) {
677 for (x = 0; x <
ARRAY_LEN(dscp_pool1); x++) {
678 if (!strcasecmp(value, dscp_pool1[x].
name)) {
679 *tos = dscp_pool1[x].
space << 2;
691 for (x = 0; x <
ARRAY_LEN(dscp_pool1); x++) {
692 if (dscp_pool1[x].
space == (tos >> 2)) {
693 return dscp_pool1[x].
name;
713 SOCK_DGRAM, 0)) < 0) {
735 ast_debug(3,
"For destination '%s', our source address is '%s'.\n",
753 ast_debug(3,
"Attached to given IP address\n");
757 if (gethostname(ourhost,
sizeof(ourhost) - 1)) {
766 ast_debug(3,
"Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\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_ha * ast_duplicate_ha_list(struct ast_ha *original)
Duplicate the contents of a list of host access rules.
struct sockaddr_storage ss
static struct dscp_codepoint dscp_pool1[]
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
char * strsep(char **str, const char *delims)
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our 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.
int ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
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.
static char ourhost[MAXHOSTNAMELEN]
enum ast_cc_service_type service
static int 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_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.
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)
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
#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...
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
#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)
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.
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
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
struct ast_sockaddr bindaddr
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
static int get_local_address(struct ast_sockaddr *ourip)
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
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.
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
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_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)
const char * ast_tos2str(unsigned int tos)
Convert a TOS value into its string representation.
#define V6_WORD(sin6, index)
Isolate a 32-bit section of an IPv6 address.
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.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
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.
void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
Copy the contents of one HA to another.
static char hostname[MAXHOSTNAMELEN]