#include <netinet/in.h>
#include "asterisk/io.h"
Go to the source code of this file.
Data Structures | |
struct | ast_ha |
Defines | |
#define | AST_SENSE_ALLOW 1 |
#define | AST_SENSE_DENY 0 |
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. | |
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. |
Definition in file acl.h.
#define AST_SENSE_ALLOW 1 |
Definition at line 35 of file acl.h.
Referenced by ast_append_ha(), ast_apply_ha(), and parse_register_contact().
#define AST_SENSE_DENY 0 |
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 }
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 }