Wed Jan 8 2020 09:49:52

Asterisk developer's documentation


acl.c File Reference

Various sorts of access control. More...

#include "asterisk.h"
#include "asterisk/network.h"
#include <ifaddrs.h>
#include "asterisk/acl.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/srv.h"

Go to the source code of this file.

Data Structures

struct  dscp_codepoint
 

Macros

#define V6_WORD(sin6, index)   ((uint32_t *)&((sin6)->sin6_addr))[(index)]
 Isolate a 32-bit section of an IPv6 address. More...
 

Functions

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. More...
 
struct ast_haast_append_ha (const char *sense, const char *stuff, struct ast_ha *path, int *error)
 Add a new rule to a list of HAs. More...
 
int ast_apply_ha (const struct ast_ha *ha, const struct ast_sockaddr *addr)
 Apply a set of rules to a given IP address. More...
 
void ast_copy_ha (const struct ast_ha *from, struct ast_ha *to)
 Copy the contents of one HA to another. More...
 
static struct ast_haast_duplicate_ha (struct ast_ha *original)
 
struct ast_haast_duplicate_ha_list (struct ast_ha *original)
 Duplicate the contents of a list of host access rules. More...
 
int ast_find_ourip (struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
 Find our IP address. More...
 
void ast_free_ha (struct ast_ha *ha)
 Free a list of HAs. More...
 
int ast_get_ip (struct ast_sockaddr *addr, const char *hostname)
 Get the IP address given a hostname. More...
 
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. More...
 
int ast_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us)
 Get our local IP address when contacting a remote host. More...
 
int ast_str2cos (const char *value, unsigned int *cos)
 Convert a string to the appropriate COS value. More...
 
int ast_str2tos (const char *value, unsigned int *tos)
 Convert a string to the appropriate TOS value. More...
 
const char * ast_tos2str (unsigned int tos)
 Convert a TOS value into its string representation. More...
 
static int get_local_address (struct ast_sockaddr *ourip)
 
static int parse_cidr_mask (struct ast_sockaddr *addr, int is_v4, const char *mask_str)
 Parse a netmask in CIDR notation. More...
 
static int resolve_first (struct ast_sockaddr *addr, const char *name, int flag, int family)
 
static void score_address (const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
 

Variables

static struct dscp_codepoint dscp_pool1 []
 

Detailed Description

Various sorts of access control.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file acl.c.

Macro Definition Documentation

#define V6_WORD (   sin6,
  index 
)    ((uint32_t *)&((sin6)->sin6_addr))[(index)]

Isolate a 32-bit section of an IPv6 address.

An IPv6 address can be divided into 4 32-bit chunks. This gives easy access to one of these chunks.

Parameters
sin6A pointer to a struct sockaddr_in6
indexWhich 32-bit chunk to operate on. Must be in the range 0-3.

Definition at line 288 of file acl.c.

Referenced by apply_netmask(), and parse_cidr_mask().

Function Documentation

static int apply_netmask ( const struct ast_sockaddr addr,
const struct ast_sockaddr netmask,
struct ast_sockaddr result 
)
static

Apply a netmask to an address and store the result in a separate structure.

When dealing with IPv6 addresses, one cannot apply a netmask with a simple logical and operation. Furthermore, the incoming address may be an IPv4 address and need to be mapped properly before attempting to apply a rule.

Parameters
addrThe IP address to apply the mask to.
netmaskThe netmask configured in the host access rule.
resultThe resultant address after applying the netmask to the given address
Return values
0Successfully applied netmask -1 Failed to apply netmask

Definition at line 304 of file acl.c.

References ast_sockaddr_from_sin, ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv6(), ast_sockaddr::len, ast_sockaddr::ss, and V6_WORD.

Referenced by ast_append_ha(), and ast_apply_ha().

306 {
307  int res = 0;
308 
309  if (ast_sockaddr_is_ipv4(addr)) {
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;
315  ast_sockaddr_from_sin(result, &result4);
316  } else if (ast_sockaddr_is_ipv6(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;
320  int i;
321  result6.sin6_family = AF_INET6;
322  for (i = 0; i < 4; ++i) {
323  V6_WORD(&result6, i) = V6_WORD(addr6, i) & V6_WORD(mask6, i);
324  }
325  memcpy(&result->ss, &result6, sizeof(result6));
326  result->len = sizeof(result6);
327  } else {
328  /* Unsupported address scheme */
329  res = -1;
330  }
331 
332  return res;
333 }
struct sockaddr_storage ss
Definition: netsock2.h:64
socklen_t len
Definition: netsock2.h:65
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:400
#define V6_WORD(sin6, index)
Isolate a 32-bit section of an IPv6 address.
Definition: acl.c:288
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
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.

This adds the new host access rule to the end of the list whose head is specified by the path parameter. Rules are evaluated in a way such that if multiple rules apply to a single IP address/subnet mask, then the rule latest in the list will be used.

Parameters
senseEither "permit" or "deny" (Actually any 'p' word will result in permission, and any other word will result in denial)
stuffThe IP address and subnet mask, separated with a '/'. The subnet mask can either be in dotted-decimal format or in CIDR notation (i.e. 0-32).
pathThe head of the HA list to which we wish to append our new rule. If NULL is passed, then the new rule will become the head of the list
[out]errorThe integer error points to will be set non-zero if an error occurs
Returns
The head of the HA list

Definition at line 399 of file acl.c.

References ast_ha::addr, apply_netmask(), ast_calloc, ast_debug, ast_free_ha(), ast_log(), AST_SENSE_ALLOW, AST_SENSE_DENY, ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strdupa, LOG_NOTICE, LOG_WARNING, ast_ha::netmask, ast_ha::next, parse_cidr_mask(), PARSE_PORT_FORBID, ast_ha::sense, and strsep().

Referenced by __init_manager(), add_calltoken_ignore(), build_callno_limits(), build_device(), build_gateway(), build_peer(), build_user(), config_parse_variables(), and reload_config().

400 {
401  struct ast_ha *ha;
402  struct ast_ha *prev = NULL;
403  struct ast_ha *ret;
404  char *tmp = ast_strdupa(stuff);
405  char *address = NULL, *mask = NULL;
406  int addr_is_v4;
407 
408  ret = path;
409  while (path) {
410  prev = path;
411  path = path->next;
412  }
413 
414  if (!(ha = ast_calloc(1, sizeof(*ha)))) {
415  if (error) {
416  *error = 1;
417  }
418  return ret;
419  }
420 
421  address = strsep(&tmp, "/");
422  if (!address) {
423  address = tmp;
424  } else {
425  mask = tmp;
426  }
427 
428  if (!ast_sockaddr_parse(&ha->addr, address, PARSE_PORT_FORBID)) {
429  ast_log(LOG_WARNING, "Invalid IP address: %s\n", address);
430  ast_free_ha(ha);
431  if (error) {
432  *error = 1;
433  }
434  return ret;
435  }
436 
437  /* If someone specifies an IPv4-mapped IPv6 address,
438  * we just convert this to an IPv4 ACL
439  */
440  if (ast_sockaddr_ipv4_mapped(&ha->addr, &ha->addr)) {
441  ast_log(LOG_NOTICE, "IPv4-mapped ACL network address specified. "
442  "Converting to an IPv4 ACL network address.\n");
443  }
444 
445  addr_is_v4 = ast_sockaddr_is_ipv4(&ha->addr);
446 
447  if (!mask) {
448  parse_cidr_mask(&ha->netmask, addr_is_v4, addr_is_v4 ? "32" : "128");
449  } else if (strchr(mask, ':') || strchr(mask, '.')) {
450  int mask_is_v4;
451  /* Mask is of x.x.x.x or x:x:x:x:x:x:x:x variety */
452  if (!ast_sockaddr_parse(&ha->netmask, mask, PARSE_PORT_FORBID)) {
453  ast_log(LOG_WARNING, "Invalid netmask: %s\n", mask);
454  ast_free_ha(ha);
455  if (error) {
456  *error = 1;
457  }
458  return ret;
459  }
460  /* If someone specifies an IPv4-mapped IPv6 netmask,
461  * we just convert this to an IPv4 ACL
462  */
463  if (ast_sockaddr_ipv4_mapped(&ha->netmask, &ha->netmask)) {
464  ast_log(LOG_NOTICE, "IPv4-mapped ACL netmask specified. "
465  "Converting to an IPv4 ACL netmask.\n");
466  }
467  mask_is_v4 = ast_sockaddr_is_ipv4(&ha->netmask);
468  if (addr_is_v4 ^ mask_is_v4) {
469  ast_log(LOG_WARNING, "Address and mask are not using same address scheme.\n");
470  ast_free_ha(ha);
471  if (error) {
472  *error = 1;
473  }
474  return ret;
475  }
476  } else if (parse_cidr_mask(&ha->netmask, addr_is_v4, mask)) {
477  ast_log(LOG_WARNING, "Invalid CIDR netmask: %s\n", mask);
478  ast_free_ha(ha);
479  if (error) {
480  *error = 1;
481  }
482  return ret;
483  }
484 
485  if (apply_netmask(&ha->addr, &ha->netmask, &ha->addr)) {
486  /* This shouldn't happen because ast_sockaddr_parse would
487  * have failed much earlier on an unsupported address scheme
488  */
489  char *failmask = ast_strdupa(ast_sockaddr_stringify(&ha->netmask));
490  char *failaddr = ast_strdupa(ast_sockaddr_stringify(&ha->addr));
491  ast_log(LOG_WARNING, "Unable to apply netmask %s to address %s\n", failmask, failaddr);
492  ast_free_ha(ha);
493  if (error) {
494  *error = 1;
495  }
496  return ret;
497  }
498 
499  ha->sense = strncasecmp(sense, "p", 1) ? AST_SENSE_DENY : AST_SENSE_ALLOW;
500 
501  ha->next = NULL;
502  if (prev) {
503  prev->next = ha;
504  } else {
505  ret = ha;
506  }
507 
508  {
509  const char *addr = ast_strdupa(ast_sockaddr_stringify(&ha->addr));
510  const char *mask = ast_strdupa(ast_sockaddr_stringify(&ha->netmask));
511 
512  ast_debug(1, "%s/%s sense %d appended to acl for peer\n", addr, mask, ha->sense);
513  }
514 
515  return ret;
516 }
struct ast_ha * next
Definition: acl.h:53
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.
Definition: netsock2.c:198
struct ast_sockaddr addr
Definition: acl.h:50
#define LOG_WARNING
Definition: logger.h:144
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.
Definition: netsock2.c:39
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.
Definition: acl.c:304
static int parse_cidr_mask(struct ast_sockaddr *addr, int is_v4, const char *mask_str)
Parse a netmask in CIDR notation.
Definition: acl.c:351
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_sockaddr netmask
Definition: acl.h:51
#define AST_SENSE_DENY
Definition: acl.h:35
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int sense
Definition: acl.h:52
#define AST_SENSE_ALLOW
Definition: acl.h:36
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
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...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:223
#define ast_calloc(a, b)
Definition: astmm.h:82
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:400
int ast_apply_ha ( const struct ast_ha ha,
const struct ast_sockaddr addr 
)

Apply a set of rules to a given IP address.

The list of host access rules is traversed, beginning with the input rule. If the IP address given matches a rule, the "sense" of that rule is used as the return value. Note that if an IP address matches multiple rules that the last one matched will be the one whose sense will be returned.

Parameters
haThe head of the list of host access rules to follow
addrAn ast_sockaddr whose address is considered when matching rules
Return values
AST_SENSE_ALLOWThe IP address passes our ACL
AST_SENSE_DENYThe IP address fails our ACL

Definition at line 518 of file acl.c.

References ast_ha::addr, apply_netmask(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_SENSE_ALLOW, ast_sockaddr_cmp_addr(), ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_stringify(), LOG_ERROR, ast_ha::netmask, ast_ha::next, and ast_ha::sense.

Referenced by apply_directmedia_ha(), ast_sip_ouraddrfor(), auth_http_callback(), authenticate(), check_access(), check_peer_ok(), parse_register_contact(), register_verify(), and skinny_register().

519 {
520  /* Start optimistic */
521  int res = AST_SENSE_ALLOW;
522  const struct ast_ha *current_ha;
523 
524  for (current_ha = ha; current_ha; current_ha = current_ha->next) {
525  struct ast_sockaddr result;
526  struct ast_sockaddr mapped_addr;
527  const struct ast_sockaddr *addr_to_use;
528 #if 0 /* debugging code */
529  char iabuf[INET_ADDRSTRLEN];
530  char iabuf2[INET_ADDRSTRLEN];
531  /* DEBUG */
532  ast_copy_string(iabuf, ast_inet_ntoa(sin->sin_addr), sizeof(iabuf));
533  ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
534  ast_debug(1, "##### Testing %s with %s\n", iabuf, iabuf2);
535 #endif
536  if (ast_sockaddr_is_ipv4(&current_ha->addr)) {
537  if (ast_sockaddr_is_ipv6(addr)) {
538  if (ast_sockaddr_is_ipv4_mapped(addr)) {
539  /* IPv4 ACLs apply to IPv4-mapped addresses */
540  if (!ast_sockaddr_ipv4_mapped(addr, &mapped_addr)) {
541  ast_log(LOG_ERROR, "%s provided to ast_sockaddr_ipv4_mapped could not be converted. That shouldn't be possible.\n",
542  ast_sockaddr_stringify(addr));
543  continue;
544  }
545  addr_to_use = &mapped_addr;
546  } else {
547  /* An IPv4 ACL does not apply to an IPv6 address */
548  continue;
549  }
550  } else {
551  /* Address is IPv4 and ACL is IPv4. No biggie */
552  addr_to_use = addr;
553  }
554  } else {
556  addr_to_use = addr;
557  } else {
558  /* Address is IPv4 or IPv4 mapped but ACL is IPv6. Skip */
559  continue;
560  }
561  }
562 
563  /* For each rule, if this address and the netmask = the net address
564  apply the current rule */
565  if (apply_netmask(addr_to_use, &current_ha->netmask, &result)) {
566  /* Unlikely to happen since we know the address to be IPv4 or IPv6 */
567  continue;
568  }
569  if (!ast_sockaddr_cmp_addr(&result, &current_ha->addr)) {
570  res = current_ha->sense;
571  }
572  }
573  return res;
574 }
struct ast_ha * next
Definition: acl.h:53
struct ast_sockaddr addr
Definition: acl.h:50
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.
Definition: netsock2.c:39
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.
Definition: acl.c:304
Socket address structure.
Definition: netsock2.h:63
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:325
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_sockaddr netmask
Definition: acl.h:51
int sense
Definition: acl.h:52
#define LOG_ERROR
Definition: logger.h:155
#define AST_SENSE_ALLOW
Definition: acl.h:36
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
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...
Definition: logger.c:1207
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:406
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:400
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
void ast_copy_ha ( const struct ast_ha from,
struct ast_ha to 
)

Copy the contents of one HA to another.

This copies the internals of the 'from' HA to the 'to' HA. It is important that the 'to' HA has been allocated prior to calling this function

Parameters
fromSource HA to copy
toDestination HA to copy to
Return values
void

Definition at line 234 of file acl.c.

References ast_ha::addr, ast_sockaddr_copy(), ast_ha::netmask, and ast_ha::sense.

Referenced by add_calltoken_ignore(), ast_duplicate_ha(), and build_callno_limits().

235 {
236  ast_sockaddr_copy(&to->addr, &from->addr);
237  ast_sockaddr_copy(&to->netmask, &from->netmask);
238  to->sense = from->sense;
239 }
struct ast_sockaddr addr
Definition: acl.h:50
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
struct ast_sockaddr netmask
Definition: acl.h:51
int sense
Definition: acl.h:52
static struct ast_ha* ast_duplicate_ha ( struct ast_ha original)
static

Definition at line 242 of file acl.c.

References ast_calloc, and ast_copy_ha().

Referenced by ast_duplicate_ha_list().

243 {
244  struct ast_ha *new_ha;
245 
246  if ((new_ha = ast_calloc(1, sizeof(*new_ha)))) {
247  /* Copy from original to new object */
248  ast_copy_ha(original, new_ha);
249  }
250 
251  return new_ha;
252 }
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
Copy the contents of one HA to another.
Definition: acl.c:234
struct ast_ha* ast_duplicate_ha_list ( struct ast_ha original)

Duplicate the contents of a list of host access rules.

A deep copy of all ast_has in the list is made. The returned value is allocated on the heap and must be freed independently of the input parameter when finished.

Note
This function is not actually used anywhere.
Parameters
originalThe ast_ha to copy
Return values
Thehead of the list of duplicated ast_has

Definition at line 256 of file acl.c.

References ast_duplicate_ha(), and ast_ha::next.

Referenced by create_addr_from_peer().

257 {
258  struct ast_ha *start = original;
259  struct ast_ha *ret = NULL;
260  struct ast_ha *current, *prev = NULL;
261 
262  while (start) {
263  current = ast_duplicate_ha(start); /* Create copy of this object */
264  if (prev) {
265  prev->next = current; /* Link previous to this object */
266  }
267 
268  if (!ret) {
269  ret = current; /* Save starting point */
270  }
271 
272  start = start->next; /* Go to next object */
273  prev = current; /* Save pointer to this object */
274  }
275  return ret; /* Return start of list */
276 }
struct ast_ha * next
Definition: acl.h:53
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
static struct ast_ha * ast_duplicate_ha(struct ast_ha *original)
Definition: acl.c:242
int ast_find_ourip ( struct ast_sockaddr ourip,
const struct ast_sockaddr bindaddr,
int  family 
)

Find our IP address.

This function goes through many iterations in an attempt to find our IP address. If any step along the way should fail, we move to the next item in the list. Here are the steps taken:

  • If bindaddr has a non-zero IP address, that is copied into ourip
  • We use a combination of gethostname and ast_gethostbyname to find our IP address.
  • We use ast_ouraddrfor with 198.41.0.4 as the destination IP address
  • We try some platform-specific socket operations to find the IP address
Parameters
[out]ouripOur IP address is written here when it is found
bindaddrA hint used for finding our IP. See the steps above for more details
familyOnly addresses of the given family will be returned. Use 0 or AST_SOCKADDR_UNSPEC to get addresses of all families.
Return values
0Success
-1Failure

Definition at line 744 of file acl.c.

References ast_debug, ast_log(), ast_ouraddrfor(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_port, ast_sockaddr_set_port, get_local_address(), LOG_WARNING, MAXHOSTNAMELEN, ourhost, PARSE_PORT_FORBID, and resolve_first().

Referenced by __oh323_rtp_create(), gtalk_get_local_ip(), jingle_create_candidates(), load_module(), and reload_config().

745 {
746  char ourhost[MAXHOSTNAMELEN] = "";
747  struct ast_sockaddr root;
748  int res, port = ast_sockaddr_port(ourip);
749 
750  /* just use the bind address if it is nonzero */
751  if (!ast_sockaddr_is_any(bindaddr)) {
752  ast_sockaddr_copy(ourip, bindaddr);
753  ast_debug(3, "Attached to given IP address\n");
754  return 0;
755  }
756  /* try to use our hostname */
757  if (gethostname(ourhost, sizeof(ourhost) - 1)) {
758  ast_log(LOG_WARNING, "Unable to get hostname\n");
759  } else {
760  if (resolve_first(ourip, ourhost, PARSE_PORT_FORBID, family) == 0) {
761  /* reset port since resolve_first wipes this out */
762  ast_sockaddr_set_port(ourip, port);
763  return 0;
764  }
765  }
766  ast_debug(3, "Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
767  /* A.ROOT-SERVERS.NET. */
768  if (!resolve_first(&root, "A.ROOT-SERVERS.NET", PARSE_PORT_FORBID, 0) &&
769  !ast_ouraddrfor(&root, ourip)) {
770  /* reset port since resolve_first wipes this out */
771  ast_sockaddr_set_port(ourip, port);
772  return 0;
773  }
774  res = get_local_address(ourip);
775  ast_sockaddr_set_port(ourip, port);
776  return res;
777 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
#define LOG_WARNING
Definition: logger.h:144
static char ourhost[MAXHOSTNAMELEN]
Definition: chan_mgcp.c:231
#define MAXHOSTNAMELEN
Definition: network.h:69
Socket address structure.
Definition: netsock2.h:63
static int resolve_first(struct ast_sockaddr *addr, const char *name, int flag, int family)
Definition: acl.c:576
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:705
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or &quot;any&quot; address.
Definition: netsock2.c:424
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
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...
Definition: logger.c:1207
static int get_local_address(struct ast_sockaddr *ourip)
Definition: acl.c:119
void ast_free_ha ( struct ast_ha ha)

Free a list of HAs.

Given the head of a list of HAs, it and all appended HAs are freed

Parameters
haThe head of the list of HAs to free
Return values
void

Definition at line 223 of file acl.c.

References ast_free, and ast_ha::next.

Referenced by __init_manager(), __sip_destroy(), add_calltoken_ignore(), ast_append_ha(), build_callno_limits(), build_peer(), build_user(), destroy_gateway(), manager_free_user(), oh323_destroy_peer(), oh323_destroy_user(), peer_destructor(), reload_config(), sip_destroy_peer(), unload_module(), and user_destructor().

224 {
225  struct ast_ha *hal;
226  while (ha) {
227  hal = ha;
228  ha = ha->next;
229  ast_free(hal);
230  }
231 }
struct ast_ha * next
Definition: acl.h:53
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
#define ast_free(a)
Definition: astmm.h:97
int ast_get_ip ( struct ast_sockaddr addr,
const char *  hostname 
)

Get the IP address given a hostname.

Similar in nature to ast_gethostbyname, except that instead of getting an entire hostent structure, you instead are given only the IP address inserted into a ast_sockaddr structure.

Parameters
addrThe IP address found. The address family is used as an input parameter to filter the returned addresses. If it is 0, both IPv4 and IPv6 addresses can be returned.
hostnameThe hostname to look up
Return values
0Success
-1Failure

Definition at line 700 of file acl.c.

References ast_get_ip_or_srv().

Referenced by build_gateway(), build_peer(), build_user(), config_parse_variables(), peer_set_srcaddr(), setup_stunaddr(), and stun_monitor_request().

701 {
702  return ast_get_ip_or_srv(addr, hostname, NULL);
703 }
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.
Definition: acl.c:597
static char hostname[MAXHOSTNAMELEN]
Definition: logger.c:91
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.

If the service parameter is non-NULL, then an SRV lookup will be made by prepending the service to the hostname parameter, separated by a '.' For example, if hostname is "example.com" and service is "_sip._udp" then an SRV lookup will be done for "_sip._udp.example.com". If service is NULL, then this function acts exactly like a call to ast_get_ip.

Parameters
addrThe IP address found. The address family is used as an input parameter to filter the returned addresses. If it is 0, both IPv4 and IPv6 addresses can be returned.
hostnameThe hostname to look up
serviceA specific service provided by the host. A NULL service results in an A-record lookup instead of an SRV lookup
Return values
0Success
-1Failure

Definition at line 597 of file acl.c.

References ast_get_srv(), ast_sockaddr_set_port, PARSE_PORT_FORBID, resolve_first(), and ast_sockaddr::ss.

Referenced by ast_get_ip(), create_addr(), dnsmgr_refresh(), internal_dnsmgr_lookup(), and proxy_update().

598 {
599  char srv[256];
600  char host[256];
601  int srv_ret = 0;
602  int tportno;
603 
604  if (service) {
605  snprintf(srv, sizeof(srv), "%s.%s", service, hostname);
606  if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, srv)) > 0) {
607  hostname = host;
608  }
609  }
610 
611  if (resolve_first(addr, hostname, PARSE_PORT_FORBID, addr->ss.ss_family) != 0) {
612  return -1;
613  }
614 
615  if (srv_ret > 0) {
616  ast_sockaddr_set_port(addr, tportno);
617  }
618 
619  return 0;
620 }
struct sockaddr_storage ss
Definition: netsock2.h:64
enum ast_cc_service_type service
Definition: chan_sip.c:821
static int resolve_first(struct ast_sockaddr *addr, const char *name, int flag, int family)
Definition: acl.c:576
int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
Definition: srv.c:263
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
static char hostname[MAXHOSTNAMELEN]
Definition: logger.c:91
int ast_ouraddrfor ( const struct ast_sockaddr them,
struct ast_sockaddr us 
)

Get our local IP address when contacting a remote host.

This function will attempt to connect(2) to them over UDP using a source port of 5060. If the connect(2) call is successful, then we inspect the sockaddr_in output parameter of connect(2) to determine the IP address used to connect to them. This IP address is then copied into us.

Parameters
themThe IP address to which we wish to attempt to connect
[out]usThe source IP address used to connect to them
Return values
-1Failure
0Success

Definition at line 705 of file acl.c.

References ast_connect(), ast_debug, ast_getsockname(), ast_log(), ast_sockaddr_is_ipv6(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify_addr(), ast_strdupa, LOG_ERROR, and LOG_WARNING.

Referenced by ast_find_ourip(), ast_sip_ouraddrfor(), build_gateway(), find_subchannel_and_lock(), gtalk_get_local_ip(), and sip_acf_channel_read().

706 {
707  int port;
708  int s;
709 
710  port = ast_sockaddr_port(us);
711 
712  if ((s = socket(ast_sockaddr_is_ipv6(them) ? AF_INET6 : AF_INET,
713  SOCK_DGRAM, 0)) < 0) {
714  ast_log(LOG_ERROR, "Cannot create socket\n");
715  return -1;
716  }
717 
718  if (ast_connect(s, them)) {
719  ast_log(LOG_WARNING, "Cannot connect\n");
720  close(s);
721  return -1;
722  }
723  if (ast_getsockname(s, us)) {
724 
725  ast_log(LOG_WARNING, "Cannot get socket name\n");
726  close(s);
727  return -1;
728  }
729  close(s);
730 
731  {
732  const char *them_addr = ast_strdupa(ast_sockaddr_stringify_addr(them));
733  const char *us_addr = ast_strdupa(ast_sockaddr_stringify_addr(us));
734 
735  ast_debug(3, "For destination '%s', our source address is '%s'.\n",
736  them_addr, us_addr);
737  }
738 
739  ast_sockaddr_set_port(us, port);
740 
741  return 0;
742 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:240
#define LOG_WARNING
Definition: logger.h:144
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
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...
Definition: logger.c:1207
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
Definition: netsock2.c:472
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
Definition: netsock2.c:467
int ast_str2cos ( const char *  value,
unsigned int *  cos 
)

Convert a string to the appropriate COS value.

Parameters
valueThe COS string to convert
[out]cosThe integer representation of that COS value
Return values
-1Failure
0Success

Definition at line 653 of file acl.c.

Referenced by config_parse_variables(), reload_config(), and set_config().

654 {
655  int fval;
656 
657  if (sscanf(value, "%30d", &fval) == 1) {
658  if (fval < 8) {
659  *cos = fval;
660  return 0;
661  }
662  }
663 
664  return -1;
665 }
int value
Definition: syslog.c:39
static unsigned int cos
Definition: chan_h323.c:147
int ast_str2tos ( const char *  value,
unsigned int *  tos 
)

Convert a string to the appropriate TOS value.

Parameters
valueThe TOS string to convert
[out]tosThe integer representation of that TOS value
Return values
-1Failure
0Success

Definition at line 667 of file acl.c.

References ARRAY_LEN, name, and dscp_codepoint::space.

Referenced by config_parse_variables(), iax_template_parse(), reload_config(), and set_config().

668 {
669  int fval;
670  unsigned int x;
671 
672  if (sscanf(value, "%30i", &fval) == 1) {
673  *tos = fval & 0xFF;
674  return 0;
675  }
676 
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;
680  return 0;
681  }
682  }
683 
684  return -1;
685 }
static struct dscp_codepoint dscp_pool1[]
Definition: acl.c:629
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static unsigned int tos
Definition: chan_h323.c:146
int value
Definition: syslog.c:39
static const char name[]
unsigned int space
Definition: acl.c:624
const char* ast_tos2str ( unsigned int  tos)

Convert a TOS value into its string representation.

Parameters
tosThe TOS value to look up
Returns
The string equivalent of the TOS value

Definition at line 687 of file acl.c.

References ARRAY_LEN, dscp_codepoint::name, and dscp_codepoint::space.

Referenced by sip_show_settings().

688 {
689  unsigned int x;
690 
691  for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
692  if (dscp_pool1[x].space == (tos >> 2)) {
693  return dscp_pool1[x].name;
694  }
695  }
696 
697  return "unknown";
698 }
static struct dscp_codepoint dscp_pool1[]
Definition: acl.c:629
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * name
Definition: acl.c:623
static unsigned int tos
Definition: chan_h323.c:146
static int get_local_address ( struct ast_sockaddr ourip)
static

Definition at line 119 of file acl.c.

References ast_sockaddr_setnull(), free, malloc, score_address(), and ast_sockaddr::ss.

Referenced by ast_find_ourip().

120 {
121  int s, res = -1;
122 #ifdef SOLARIS
123  struct lifreq *ifr = NULL;
124  struct lifnum ifn;
125  struct lifconf ifc;
126  struct sockaddr_in *sa;
127  char *buf = NULL;
128  int bufsz, x;
129 #endif /* SOLARIS */
130 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
131  struct ifaddrs *ifap, *ifaphead;
132  int rtnerr;
133  const struct sockaddr_in *sin;
134 #endif /* BSD_OR_LINUX */
135  struct in_addr best_addr;
136  int best_score = -100;
137  memset(&best_addr, 0, sizeof(best_addr));
138 
139 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
140  rtnerr = getifaddrs(&ifaphead);
141  if (rtnerr) {
142  perror(NULL);
143  return -1;
144  }
145 #endif /* BSD_OR_LINUX */
146 
147  s = socket(AF_INET, SOCK_STREAM, 0);
148 
149  if (s > 0) {
150 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
151  for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
152 
153  if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET) {
154  sin = (const struct sockaddr_in *) ifap->ifa_addr;
155  score_address(sin, &best_addr, &best_score);
156  res = 0;
157 
158  if (best_score == 0) {
159  break;
160  }
161  }
162  }
163 #endif /* BSD_OR_LINUX */
164 
165  /* There is no reason whatsoever that this shouldn't work on Linux or BSD also. */
166 #ifdef SOLARIS
167  /* Get a count of interfaces on the machine */
168  ifn.lifn_family = AF_INET;
169  ifn.lifn_flags = 0;
170  ifn.lifn_count = 0;
171  if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
172  close(s);
173  return -1;
174  }
175 
176  bufsz = ifn.lifn_count * sizeof(struct lifreq);
177  if (!(buf = malloc(bufsz))) {
178  close(s);
179  return -1;
180  }
181  memset(buf, 0, bufsz);
182 
183  /* Get a list of interfaces on the machine */
184  ifc.lifc_len = bufsz;
185  ifc.lifc_buf = buf;
186  ifc.lifc_family = AF_INET;
187  ifc.lifc_flags = 0;
188  if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
189  close(s);
190  free(buf);
191  return -1;
192  }
193 
194  for (ifr = ifc.lifc_req, x = 0; x < ifn.lifn_count; ifr++, x++) {
195  sa = (struct sockaddr_in *)&(ifr->lifr_addr);
196  score_address(sa, &best_addr, &best_score);
197  res = 0;
198 
199  if (best_score == 0) {
200  break;
201  }
202  }
203 
204  free(buf);
205 #endif /* SOLARIS */
206 
207  close(s);
208  }
209 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
210  freeifaddrs(ifaphead);
211 #endif /* BSD_OR_LINUX */
212 
213  if (res == 0 && ourip) {
214  ast_sockaddr_setnull(ourip);
215  ourip->ss.ss_family = AF_INET;
216  ((struct sockaddr_in *)&ourip->ss)->sin_addr = best_addr;
217  }
218  return res;
219 }
struct sockaddr_storage ss
Definition: netsock2.h:64
#define malloc(a)
Definition: astmm.h:88
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
static void score_address(const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
Definition: acl.c:60
#define free(a)
Definition: astmm.h:94
static int parse_cidr_mask ( struct ast_sockaddr addr,
int  is_v4,
const char *  mask_str 
)
static

Parse a netmask in CIDR notation.

For a mask of an IPv4 address, this should be a number between 0 and 32. For a mask of an IPv6 address, this should be a number between 0 and 128. This function creates an IPv6 ast_sockaddr from the given netmask. For masks of IPv4 addresses, this is accomplished by adding 96 to the original netmask.

Parameters
[out]addrThe ast_sockaddr produced from the CIDR netmask
is_v4Tells if the address we are masking is IPv4.
mask_strThe CIDR mask to convert
Return values
-1Failure
0Success

Definition at line 351 of file acl.c.

References ast_sockaddr_from_sin, ast_sockaddr::len, ast_sockaddr::ss, and V6_WORD.

Referenced by ast_append_ha().

352 {
353  int mask;
354 
355  if (sscanf(mask_str, "%30d", &mask) != 1) {
356  return -1;
357  }
358 
359  if (is_v4) {
360  struct sockaddr_in sin;
361  if (mask < 0 || mask > 32) {
362  return -1;
363  }
364  memset(&sin, 0, sizeof(sin));
365  sin.sin_family = AF_INET;
366  /* If mask is 0, then we already have the
367  * appropriate all 0s address in sin from
368  * the above memset.
369  */
370  if (mask != 0) {
371  sin.sin_addr.s_addr = htonl(0xFFFFFFFF << (32 - mask));
372  }
373  ast_sockaddr_from_sin(addr, &sin);
374  } else {
375  struct sockaddr_in6 sin6;
376  int i;
377  if (mask < 0 || mask > 128) {
378  return -1;
379  }
380  memset(&sin6, 0, sizeof(sin6));
381  sin6.sin6_family = AF_INET6;
382  for (i = 0; i < 4; ++i) {
383  /* Once mask reaches 0, we don't have
384  * to explicitly set anything anymore
385  * since sin6 was zeroed out already
386  */
387  if (mask > 0) {
388  V6_WORD(&sin6, i) = htonl(0xFFFFFFFF << (mask < 32 ? (32 - mask) : 0));
389  mask -= mask < 32 ? mask : 32;
390  }
391  }
392  memcpy(&addr->ss, &sin6, sizeof(sin6));
393  addr->len = sizeof(sin6);
394  }
395 
396  return 0;
397 }
struct sockaddr_storage ss
Definition: netsock2.h:64
socklen_t len
Definition: netsock2.h:65
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
#define V6_WORD(sin6, index)
Isolate a 32-bit section of an IPv6 address.
Definition: acl.c:288
static int resolve_first ( struct ast_sockaddr addr,
const char *  name,
int  flag,
int  family 
)
static

Definition at line 576 of file acl.c.

References ast_debug, ast_free, ast_log(), ast_sockaddr_copy(), ast_sockaddr_resolve(), and LOG_WARNING.

Referenced by ast_find_ourip(), and ast_get_ip_or_srv().

578 {
579  struct ast_sockaddr *addrs;
580  int addrs_cnt;
581 
582  addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
583  if (addrs_cnt > 0) {
584  if (addrs_cnt > 1) {
585  ast_debug(1, "Multiple addresses. Using the first only\n");
586  }
587  ast_sockaddr_copy(addr, &addrs[0]);
588  ast_free(addrs);
589  } else {
590  ast_log(LOG_WARNING, "Unable to lookup '%s'\n", name);
591  return -1;
592  }
593 
594  return 0;
595 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
#define LOG_WARNING
Definition: logger.h:144
Socket address structure.
Definition: netsock2.h:63
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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...
Definition: logger.c:1207
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
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.
Definition: netsock2.c:248
static void score_address ( const struct sockaddr_in *  sin,
struct in_addr *  best_addr,
int *  best_score 
)
static
Note
Better score than a test network, but not quite as good as RFC 1918 address space. The reason is that some Linux distributions automatically configure a Zeroconf address before trying DHCP, so we want to prefer a DHCP lease to a Zeroconf address.

Definition at line 60 of file acl.c.

References ast_inet_ntoa().

Referenced by get_local_address().

61 {
62  const char *address;
63  int score;
64 
65  address = ast_inet_ntoa(sin->sin_addr);
66 
67  /* RFC 1700 alias for the local network */
68  if (address[0] == '0') {
69  score = -25;
70  /* RFC 1700 localnet */
71  } else if (strncmp(address, "127", 3) == 0) {
72  score = -20;
73  /* RFC 1918 non-public address space */
74  } else if (strncmp(address, "10.", 3) == 0) {
75  score = -5;
76  /* RFC 1918 non-public address space */
77  } else if (strncmp(address, "172", 3) == 0) {
78  /* 172.16.0.0 - 172.19.255.255, but not 172.160.0.0 - 172.169.255.255 */
79  if (address[4] == '1' && address[5] >= '6' && address[6] == '.') {
80  score = -5;
81  /* 172.20.0.0 - 172.29.255.255, but not 172.200.0.0 - 172.255.255.255 nor 172.2.0.0 - 172.2.255.255 */
82  } else if (address[4] == '2' && address[6] == '.') {
83  score = -5;
84  /* 172.30.0.0 - 172.31.255.255, but not 172.3.0.0 - 172.3.255.255 */
85  } else if (address[4] == '3' && (address[5] == '0' || address[5] == '1')) {
86  score = -5;
87  /* All other 172 addresses are public */
88  } else {
89  score = 0;
90  }
91  /* RFC 2544 Benchmark test range (198.18.0.0 - 198.19.255.255, but not 198.180.0.0 - 198.199.255.255) */
92  } else if (strncmp(address, "198.1", 5) == 0 && address[5] >= '8' && address[6] == '.') {
93  score = -10;
94  /* RFC 1918 non-public address space */
95  } else if (strncmp(address, "192.168", 7) == 0) {
96  score = -5;
97  /* RFC 3330 Zeroconf network */
98  } else if (strncmp(address, "169.254", 7) == 0) {
99  /*!\note Better score than a test network, but not quite as good as RFC 1918
100  * address space. The reason is that some Linux distributions automatically
101  * configure a Zeroconf address before trying DHCP, so we want to prefer a
102  * DHCP lease to a Zeroconf address.
103  */
104  score = -10;
105  /* RFC 3330 Test network */
106  } else if (strncmp(address, "192.0.2.", 8) == 0) {
107  score = -15;
108  /* Every other address should be publically routable */
109  } else {
110  score = 0;
111  }
112 
113  if (score > *best_score) {
114  *best_score = score;
115  memcpy(best_addr, &sin->sin_addr, sizeof(*best_addr));
116  }
117 }
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564

Variable Documentation

struct dscp_codepoint dscp_pool1[]
static

Definition at line 629 of file acl.c.