#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include "asterisk/acl.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/options.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 |
struct | my_ifreq |
Defines | |
#define | IPTOS_LOWCOST 0x02 |
#define | IPTOS_MINCOST IPTOS_LOWCOST |
Functions | |
ast_ha * | ast_append_ha (char *sense, const char *stuff, struct ast_ha *path) |
Add a new rule to a list of HAs. | |
int | ast_apply_ha (struct ast_ha *ha, struct sockaddr_in *sin) |
Apply a set of rules to a given IP address. | |
void | ast_copy_ha (const struct ast_ha *from, struct ast_ha *to) |
Copy the contents of one HA to another. | |
static struct ast_ha * | ast_duplicate_ha (struct ast_ha *original) |
ast_ha * | ast_duplicate_ha_list (struct ast_ha *original) |
Duplicate the contents of a list of host access rules. | |
int | ast_find_ourip (struct in_addr *ourip, struct sockaddr_in bindaddr) |
Find our IP address. | |
void | ast_free_ha (struct ast_ha *ha) |
Free a list of HAs. | |
int | ast_get_ip (struct sockaddr_in *sin, const char *value) |
Get the IP address given a hostname. | |
int | ast_get_ip_or_srv (struct sockaddr_in *sin, const char *value, const char *service) |
Get the IP address given a hostname and optional service. | |
int | ast_lookup_iface (char *iface, struct in_addr *address) |
Find an IP address associated with a specific interface. | |
int | ast_ouraddrfor (struct in_addr *them, struct in_addr *us) |
Get our local IP address when contacting a remote host. | |
int | ast_str2tos (const char *value, unsigned int *tos) |
Convert a string to the appropriate TOS value. | |
const char * | ast_tos2str (unsigned int tos) |
Convert a TOS value into its string representation. | |
static int | get_local_address (struct in_addr *ourip) |
static void | score_address (const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score) |
Variables | |
static struct in_addr | __ourip = { .s_addr = 0x00000000, } |
static struct dscp_codepoint | dscp_pool1 [] |
Definition in file acl.c.
#define IPTOS_MINCOST IPTOS_LOWCOST |
Definition at line 64 of file acl.c.
Referenced by ast_str2tos(), ast_tos2str(), reload_config(), and set_config().
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.
sense | Either "permit" or "deny" (Actually any 'p' word will result in permission, and any other word will result in denial) | |
stuff | The 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). | |
path | The 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 |
Definition at line 298 of file acl.c.
References ast_copy_string(), ast_log(), ast_malloc, AST_SENSE_ALLOW, AST_SENSE_DENY, free, LOG_DEBUG, LOG_WARNING, ast_ha::netaddr, ast_ha::next, and option_debug.
Referenced by add_calltoken_ignore(), authenticate(), build_callno_limits(), build_device(), build_gateway(), build_peer(), and build_user().
00299 { 00300 struct ast_ha *ha; 00301 char *nm = "255.255.255.255"; 00302 char tmp[256]; 00303 struct ast_ha *prev = NULL; 00304 struct ast_ha *ret; 00305 int x, z; 00306 unsigned int y; 00307 00308 ret = path; 00309 while (path) { 00310 prev = path; 00311 path = path->next; 00312 } 00313 if ((ha = ast_malloc(sizeof(*ha)))) { 00314 ast_copy_string(tmp, stuff, sizeof(tmp)); 00315 nm = strchr(tmp, '/'); 00316 if (!nm) { 00317 nm = "255.255.255.255"; 00318 } else { 00319 *nm = '\0'; 00320 nm++; 00321 } 00322 if (!strchr(nm, '.')) { 00323 if ((sscanf(nm, "%30d", &x) == 1) && (x >= 0) && (x <= 32)) { 00324 y = 0; 00325 for (z = 0; z < x; z++) { 00326 y >>= 1; 00327 y |= 0x80000000; 00328 } 00329 ha->netmask.s_addr = htonl(y); 00330 } 00331 } else if (!inet_aton(nm, &ha->netmask)) { 00332 ast_log(LOG_WARNING, "%s is not a valid netmask\n", nm); 00333 free(ha); 00334 return ret; 00335 } 00336 if (!inet_aton(tmp, &ha->netaddr)) { 00337 ast_log(LOG_WARNING, "%s is not a valid IP\n", tmp); 00338 free(ha); 00339 return ret; 00340 } 00341 ha->netaddr.s_addr &= ha->netmask.s_addr; 00342 if (!strncasecmp(sense, "p", 1)) { 00343 ha->sense = AST_SENSE_ALLOW; 00344 } else { 00345 ha->sense = AST_SENSE_DENY; 00346 } 00347 ha->next = NULL; 00348 if (prev) { 00349 prev->next = ha; 00350 } else { 00351 ret = ha; 00352 } 00353 } 00354 if (option_debug) 00355 ast_log(LOG_DEBUG, "%s/%s appended to acl for peer\n", stuff, nm); 00356 return ret; 00357 }
int ast_apply_ha | ( | struct ast_ha * | ha, | |
struct sockaddr_in * | sin | |||
) |
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.
ha | The head of the list of host access rules to follow | |
sin | A sockaddr_in whose address is considered when matching rules |
AST_SENSE_ALLOW | The IP address passes our ACL | |
AST_SENSE_DENY | The IP address fails our ACL |
Definition at line 359 of file acl.c.
References ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SENSE_ALLOW, LOG_DEBUG, ast_ha::netaddr, ast_ha::netmask, ast_ha::next, option_debug, and ast_ha::sense.
Referenced by ast_sip_ouraddrfor(), authenticate(), check_access(), check_user_full(), parse_register_contact(), register_verify(), and skinny_register().
00360 { 00361 /* Start optimistic */ 00362 int res = AST_SENSE_ALLOW; 00363 while (ha) { 00364 char iabuf[INET_ADDRSTRLEN]; 00365 char iabuf2[INET_ADDRSTRLEN]; 00366 /* DEBUG */ 00367 ast_copy_string(iabuf, ast_inet_ntoa(sin->sin_addr), sizeof(iabuf)); 00368 ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2)); 00369 if (option_debug) 00370 ast_log(LOG_DEBUG, "##### Testing %s with %s\n", iabuf, iabuf2); 00371 /* For each rule, if this address and the netmask = the net address 00372 apply the current rule */ 00373 if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == ha->netaddr.s_addr) 00374 res = ha->sense; 00375 ha = ha->next; 00376 } 00377 return res; 00378 }
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
from | Source HA to copy | |
to | Destination HA to copy to |
void |
Definition at line 256 of file acl.c.
References ast_ha::netaddr, ast_ha::netmask, and ast_ha::sense.
Referenced by add_calltoken_ignore(), ast_duplicate_ha(), and build_callno_limits().
00257 { 00258 memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr)); 00259 memcpy(&to->netmask, &from->netmask, sizeof(from->netmask)); 00260 to->sense = from->sense; 00261 }
Definition at line 264 of file acl.c.
References ast_copy_ha(), and ast_malloc.
Referenced by ast_duplicate_ha_list().
00265 { 00266 struct ast_ha *new_ha; 00267 00268 if ((new_ha = ast_malloc(sizeof(*new_ha)))) { 00269 /* Copy from original to new object */ 00270 ast_copy_ha(original, new_ha); 00271 } 00272 00273 return new_ha; 00274 }
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.
original | The ast_ha to copy |
The | head of the list of duplicated ast_has |
Definition at line 278 of file acl.c.
References ast_duplicate_ha(), and ast_ha::next.
00279 { 00280 struct ast_ha *start = original; 00281 struct ast_ha *ret = NULL; 00282 struct ast_ha *link, *prev = NULL; 00283 00284 while (start) { 00285 link = ast_duplicate_ha(start); /* Create copy of this object */ 00286 if (prev) 00287 prev->next = link; /* Link previous to this object */ 00288 00289 if (!ret) 00290 ret = link; /* Save starting point */ 00291 00292 start = start->next; /* Go to next object */ 00293 prev = link; /* Save pointer to this object */ 00294 } 00295 return ret; /* Return start of list */ 00296 }
int ast_find_ourip | ( | struct in_addr * | ourip, | |
struct sockaddr_in | bindaddr | |||
) |
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:
[out] | ourip | Our IP address is written here when it is found |
bindaddr | A hint used for finding our IP. See the steps above for more details |
0 | Success | |
-1 | Failure |
Definition at line 556 of file acl.c.
References ahp, ast_gethostbyname(), ast_log(), ast_ouraddrfor(), get_local_address(), hp, LOG_WARNING, and ourhost.
Referenced by __oh323_rtp_create(), gtalk_create_candidates(), and load_module().
00557 { 00558 char ourhost[MAXHOSTNAMELEN] = ""; 00559 struct ast_hostent ahp; 00560 struct hostent *hp; 00561 struct in_addr saddr; 00562 00563 /* just use the bind address if it is nonzero */ 00564 if (ntohl(bindaddr.sin_addr.s_addr)) { 00565 memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip)); 00566 return 0; 00567 } 00568 /* try to use our hostname */ 00569 if (gethostname(ourhost, sizeof(ourhost) - 1)) { 00570 ast_log(LOG_WARNING, "Unable to get hostname\n"); 00571 } else { 00572 hp = ast_gethostbyname(ourhost, &ahp); 00573 if (hp) { 00574 memcpy(ourip, hp->h_addr, sizeof(*ourip)); 00575 return 0; 00576 } 00577 } 00578 /* A.ROOT-SERVERS.NET. */ 00579 if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip)) 00580 return 0; 00581 return get_local_address(ourip); 00582 }
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
ha | The head of the list of HAs to free |
void |
Definition at line 245 of file acl.c.
References free, and ast_ha::next.
Referenced by add_calltoken_ignore(), authenticate(), build_callno_limits(), build_peer(), build_user(), destroy_gateway(), oh323_destroy_peer(), oh323_destroy_user(), peer_destructor(), reload_config(), sip_destroy_peer(), sip_destroy_user(), unload_module(), and user_destructor().
00246 { 00247 struct ast_ha *hal; 00248 while (ha) { 00249 hal = ha; 00250 ha = ha->next; 00251 free(hal); 00252 } 00253 }
int ast_get_ip | ( | struct sockaddr_in * | sin, | |
const char * | value | |||
) |
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 sockaddr_in structure.
[out] | sin | The IP address is written into sin->sin_addr |
value | The hostname to look up |
0 | Success | |
-1 | Failure |
Definition at line 498 of file acl.c.
References ast_get_ip_or_srv().
Referenced by build_device(), build_gateway(), build_peer(), build_user(), and peer_set_srcaddr().
00499 { 00500 return ast_get_ip_or_srv(sin, value, NULL); 00501 }
int ast_get_ip_or_srv | ( | struct sockaddr_in * | sin, | |
const char * | value, | |||
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 value parameter, separated by a '.' For example, if value 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.
[out] | sin | The IP address is written into sin->sin_addr |
value | The hostname to look up | |
service | A specific service provided by the host. A NULL service results in an A-record lookup instead of an SRV lookup |
0 | Success | |
-1 | Failure |
Definition at line 380 of file acl.c.
References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), hp, and LOG_WARNING.
Referenced by ast_get_ip(), and build_peer().
00381 { 00382 struct hostent *hp; 00383 struct ast_hostent ahp; 00384 char srv[256]; 00385 char host[256]; 00386 int tportno = ntohs(sin->sin_port); 00387 if (inet_aton(value, &sin->sin_addr)) 00388 return 0; 00389 if (service) { 00390 snprintf(srv, sizeof(srv), "%s.%s", service, value); 00391 if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) { 00392 sin->sin_port = htons(tportno); 00393 value = host; 00394 } 00395 } 00396 hp = ast_gethostbyname(value, &ahp); 00397 if (hp) { 00398 sin->sin_family = hp->h_addrtype; 00399 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 00400 } else { 00401 ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value); 00402 return -1; 00403 } 00404 return 0; 00405 }
int ast_lookup_iface | ( | char * | iface, | |
struct in_addr * | address | |||
) |
Find an IP address associated with a specific interface.
Given an interface such as "eth0" we find the primary IP address associated with it using the SIOCGIFADDR ioctl. If the ioctl call should fail, we populate address with 0s.
iface | The interface name whose IP address we wish to find | |
[out] | address | The interface's IP address is placed into this param |
-1 | Failure. address is filled with 0s | |
0 | Success |
Definition at line 504 of file acl.c.
References ast_copy_string(), ast_log(), errno, and LOG_WARNING.
00505 { 00506 int mysock, res = 0; 00507 struct my_ifreq ifreq; 00508 00509 memset(&ifreq, 0, sizeof(ifreq)); 00510 ast_copy_string(ifreq.ifrn_name, iface, sizeof(ifreq.ifrn_name)); 00511 00512 mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 00513 res = ioctl(mysock, SIOCGIFADDR, &ifreq); 00514 00515 close(mysock); 00516 if (res < 0) { 00517 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno)); 00518 memcpy((char *)address, (char *)&__ourip, sizeof(__ourip)); 00519 return -1; 00520 } else { 00521 memcpy((char *)address, (char *)&ifreq.ifru_addr.sin_addr, sizeof(ifreq.ifru_addr.sin_addr)); 00522 return 0; 00523 } 00524 }
int ast_ouraddrfor | ( | struct in_addr * | them, | |
struct in_addr * | 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.
them | The IP address to which we wish to attempt to connect | |
[out] | us | The source IP address used to connect to them |
-1 | Failure | |
0 | Success |
Definition at line 526 of file acl.c.
References ast_log(), LOG_WARNING, and s.
Referenced by ast_find_ourip(), ast_sip_ouraddrfor(), build_device(), build_gateway(), and find_subchannel_and_lock().
00527 { 00528 int s; 00529 struct sockaddr_in sin; 00530 socklen_t slen; 00531 00532 s = socket(PF_INET, SOCK_DGRAM, 0); 00533 if (s < 0) { 00534 ast_log(LOG_WARNING, "Cannot create socket\n"); 00535 return -1; 00536 } 00537 sin.sin_family = AF_INET; 00538 sin.sin_port = htons(5060); 00539 sin.sin_addr = *them; 00540 if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) { 00541 ast_log(LOG_WARNING, "Cannot connect\n"); 00542 close(s); 00543 return -1; 00544 } 00545 slen = sizeof(sin); 00546 if (getsockname(s, (struct sockaddr *)&sin, &slen)) { 00547 ast_log(LOG_WARNING, "Cannot get socket name\n"); 00548 close(s); 00549 return -1; 00550 } 00551 close(s); 00552 *us = sin.sin_addr; 00553 return 0; 00554 }
int ast_str2tos | ( | const char * | value, | |
unsigned int * | tos | |||
) |
Convert a string to the appropriate TOS value.
value | The TOS string to convert | |
[out] | The | integer representation of that TOS value |
-1 | Failure | |
0 | Success |
Definition at line 438 of file acl.c.
References ast_log(), dscp_pool1, IPTOS_MINCOST, LOG_WARNING, name, and dscp_codepoint::space.
Referenced by iax_template_parse(), and set_config().
00439 { 00440 int fval; 00441 unsigned int x; 00442 00443 if (sscanf(value, "%30i", &fval) == 1) { 00444 *tos = fval & 0xFF; 00445 return 0; 00446 } 00447 00448 for (x = 0; x < sizeof(dscp_pool1) / sizeof(dscp_pool1[0]); x++) { 00449 if (!strcasecmp(value, dscp_pool1[x].name)) { 00450 *tos = dscp_pool1[x].space << 2; 00451 return 0; 00452 } 00453 } 00454 00455 if (!strcasecmp(value, "lowdelay")) 00456 *tos = IPTOS_LOWDELAY; 00457 else if (!strcasecmp(value, "throughput")) 00458 *tos = IPTOS_THROUGHPUT; 00459 else if (!strcasecmp(value, "reliability")) 00460 *tos = IPTOS_RELIABILITY; 00461 else if (!strcasecmp(value, "mincost")) 00462 *tos = IPTOS_MINCOST; 00463 else if (!strcasecmp(value, "none")) 00464 *tos = 0; 00465 else 00466 return -1; 00467 00468 ast_log(LOG_WARNING, "TOS value %s is deprecated. Please see doc/ip-tos.txt for more information.\n", value); 00469 00470 return 0; 00471 }
const char* ast_tos2str | ( | unsigned int | tos | ) |
Convert a TOS value into its string representation.
tos | The TOS value to look up |
Definition at line 473 of file acl.c.
References dscp_pool1, IPTOS_MINCOST, name, and dscp_codepoint::space.
Referenced by sip_show_settings().
00474 { 00475 unsigned int x; 00476 00477 switch (tos) { 00478 case 0: 00479 return "none"; 00480 case IPTOS_LOWDELAY: 00481 return "lowdelay"; 00482 case IPTOS_THROUGHPUT: 00483 return "throughput"; 00484 case IPTOS_RELIABILITY: 00485 return "reliability"; 00486 case IPTOS_MINCOST: 00487 return "mincost"; 00488 default: 00489 for (x = 0; x < sizeof(dscp_pool1) / sizeof(dscp_pool1[0]); x++) { 00490 if (dscp_pool1[x].space == (tos >> 2)) 00491 return dscp_pool1[x].name; 00492 } 00493 } 00494 00495 return "unknown"; 00496 }
static int get_local_address | ( | struct in_addr * | ourip | ) | [static] |
Definition at line 146 of file acl.c.
References free, malloc, s, and score_address().
Referenced by ast_find_ourip().
00147 { 00148 int s, res = -1; 00149 #ifdef SOLARIS 00150 struct lifreq *ifr = NULL; 00151 struct lifnum ifn; 00152 struct lifconf ifc; 00153 struct sockaddr_in *sa; 00154 char *buf = NULL; 00155 int bufsz, x; 00156 #endif /* SOLARIS */ 00157 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) 00158 struct ifaddrs *ifap, *ifaphead; 00159 int rtnerr; 00160 const struct sockaddr_in *sin; 00161 #endif /* BSD_OR_LINUX */ 00162 struct in_addr best_addr; 00163 int best_score = -100; 00164 memset(&best_addr, 0, sizeof(best_addr)); 00165 00166 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) 00167 rtnerr = getifaddrs(&ifaphead); 00168 if (rtnerr) { 00169 perror(NULL); 00170 return -1; 00171 } 00172 #endif /* BSD_OR_LINUX */ 00173 00174 s = socket(AF_INET, SOCK_STREAM, 0); 00175 00176 if (s > 0) { 00177 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) 00178 for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) { 00179 00180 if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET) { 00181 sin = (const struct sockaddr_in *) ifap->ifa_addr; 00182 score_address(sin, &best_addr, &best_score); 00183 res = 0; 00184 00185 if (best_score == 0) 00186 break; 00187 } 00188 } 00189 #endif /* BSD_OR_LINUX */ 00190 00191 /* There is no reason whatsoever that this shouldn't work on Linux or BSD also. */ 00192 #ifdef SOLARIS 00193 /* Get a count of interfaces on the machine */ 00194 ifn.lifn_family = AF_INET; 00195 ifn.lifn_flags = 0; 00196 ifn.lifn_count = 0; 00197 if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) { 00198 close(s); 00199 return -1; 00200 } 00201 00202 bufsz = ifn.lifn_count * sizeof(struct lifreq); 00203 if (!(buf = malloc(bufsz))) { 00204 close(s); 00205 return -1; 00206 } 00207 memset(buf, 0, bufsz); 00208 00209 /* Get a list of interfaces on the machine */ 00210 ifc.lifc_len = bufsz; 00211 ifc.lifc_buf = buf; 00212 ifc.lifc_family = AF_INET; 00213 ifc.lifc_flags = 0; 00214 if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) { 00215 close(s); 00216 free(buf); 00217 return -1; 00218 } 00219 00220 for (ifr = ifc.lifc_req, x = 0; x < ifn.lifn_count; ifr++, x++) { 00221 sa = (struct sockaddr_in *)&(ifr->lifr_addr); 00222 score_address(sa, &best_addr, &best_score); 00223 res = 0; 00224 00225 if (best_score == 0) 00226 break; 00227 } 00228 00229 free(buf); 00230 #endif /* SOLARIS */ 00231 00232 close(s); 00233 } 00234 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__) 00235 freeifaddrs(ifaphead); 00236 #endif /* BSD_OR_LINUX */ 00237 00238 if (res == 0 && ourip) 00239 memcpy(ourip, &best_addr, sizeof(*ourip)); 00240 return res; 00241 }
static void score_address | ( | const struct sockaddr_in * | sin, | |
struct in_addr * | best_addr, | |||
int * | best_score | |||
) | [static] |
Definition at line 89 of file acl.c.
References ast_inet_ntoa().
Referenced by get_local_address().
00090 { 00091 const char *address; 00092 int score; 00093 00094 address = ast_inet_ntoa(sin->sin_addr); 00095 00096 /* RFC 1700 alias for the local network */ 00097 if (address[0] == '0') 00098 score = -25; 00099 /* RFC 1700 localnet */ 00100 else if (strncmp(address, "127", 3) == 0) 00101 score = -20; 00102 /* RFC 1918 non-public address space */ 00103 else if (strncmp(address, "10.", 3) == 0) 00104 score = -5; 00105 /* RFC 1918 non-public address space */ 00106 else if (strncmp(address, "172", 3) == 0) { 00107 /* 172.16.0.0 - 172.19.255.255, but not 172.160.0.0 - 172.169.255.255 */ 00108 if (address[4] == '1' && address[5] >= '6' && address[6] == '.') 00109 score = -5; 00110 /* 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 */ 00111 else if (address[4] == '2' && address[6] == '.') 00112 score = -5; 00113 /* 172.30.0.0 - 172.31.255.255, but not 172.3.0.0 - 172.3.255.255 */ 00114 else if (address[4] == '3' && (address[5] == '0' || address[5] == '1')) 00115 score = -5; 00116 /* All other 172 addresses are public */ 00117 else 00118 score = 0; 00119 /* RFC 2544 Benchmark test range */ 00120 } else if (strncmp(address, "198.1", 5) == 0 && address[5] >= '8' && address[6] == '.') 00121 score = -10; 00122 /* RFC 1918 non-public address space */ 00123 else if (strncmp(address, "192.168", 7) == 0) 00124 score = -5; 00125 /* RFC 3330 Zeroconf network */ 00126 else if (strncmp(address, "169.254", 7) == 0) 00127 /*!\note Better score than a test network, but not quite as good as RFC 1918 00128 * address space. The reason is that some Linux distributions automatically 00129 * configure a Zeroconf address before trying DHCP, so we want to prefer a 00130 * DHCP lease to a Zeroconf address. 00131 */ 00132 score = -10; 00133 /* RFC 3330 Test network */ 00134 else if (strncmp(address, "192.0.2.", 8) == 0) 00135 score = -15; 00136 /* Every other address should be publically routable */ 00137 else 00138 score = 0; 00139 00140 if (score > *best_score) { 00141 *best_score = score; 00142 memcpy(best_addr, &sin->sin_addr, sizeof(*best_addr)); 00143 } 00144 }
struct in_addr __ourip = { .s_addr = 0x00000000, } [static] |
Definition at line 76 of file acl.c.
Referenced by build_device(), build_gateway(), find_subchannel_and_lock(), gtalk_create_candidates(), load_module(), reload_config(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), skinny_register(), transmit_register(), and transmit_response_using_temp().
struct dscp_codepoint dscp_pool1[] [static] |