add acl stuff
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7966 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
9943975660
commit
bba65f4a1e
|
@ -3,5 +3,6 @@
|
||||||
<param name="listen-ip" value="127.0.0.1"/>
|
<param name="listen-ip" value="127.0.0.1"/>
|
||||||
<param name="listen-port" value="8021"/>
|
<param name="listen-port" value="8021"/>
|
||||||
<param name="password" value="ClueCon"/>
|
<param name="password" value="ClueCon"/>
|
||||||
|
<!--<param name="apply-inbound-acl" value="lan"/>-->
|
||||||
</settings>
|
</settings>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
<param name="rtp-ip" value="$${local_ip_v4}"/>
|
<param name="rtp-ip" value="$${local_ip_v4}"/>
|
||||||
<param name="sip-ip" value="$${local_ip_v4}"/>
|
<param name="sip-ip" value="$${local_ip_v4}"/>
|
||||||
<param name="hold-music" value="$${moh_uri}"/>
|
<param name="hold-music" value="$${moh_uri}"/>
|
||||||
|
<!--<param name="apply-inbound-acl" value="lan"/>-->
|
||||||
|
<!--<param name="apply-register-acl" value="lan"/>-->
|
||||||
<!--<param name="dtmf-type" value="info"/>-->
|
<!--<param name="dtmf-type" value="info"/>-->
|
||||||
<param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
|
<param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
|
||||||
<!--enable to use presense and mwi -->
|
<!--enable to use presense and mwi -->
|
||||||
|
|
|
@ -1232,7 +1232,7 @@ SWITCH_DECLARE(switch_status_t) switch_poll(switch_pollfd_t * aprset, int32_t nu
|
||||||
SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t * sock, int16_t flags, switch_memory_pool_t *pool);
|
SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t * sock, int16_t flags, switch_memory_pool_t *pool);
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t **result, switch_memory_pool_t *p);
|
SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t **result, switch_memory_pool_t *p);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t **sa, switch_bool_t remote, switch_socket_t *sock);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -1591,6 +1591,8 @@ SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void);
|
||||||
SWITCH_DECLARE(void) switch_core_setrlimits(void);
|
SWITCH_DECLARE(void) switch_core_setrlimits(void);
|
||||||
SWITCH_DECLARE(void) switch_time_sync(void);
|
SWITCH_DECLARE(void) switch_time_sync(void);
|
||||||
SWITCH_DECLARE(time_t) switch_timestamp(time_t *t);
|
SWITCH_DECLARE(time_t) switch_timestamp(time_t *t);
|
||||||
|
SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload);
|
||||||
|
SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip(const char *ip_str, const char *list_name);
|
||||||
|
|
||||||
///\}
|
///\}
|
||||||
|
|
||||||
|
|
|
@ -1259,6 +1259,9 @@ typedef struct switch_hash switch_hash_t;
|
||||||
struct HashElem;
|
struct HashElem;
|
||||||
typedef struct HashElem switch_hash_index_t;
|
typedef struct HashElem switch_hash_index_t;
|
||||||
|
|
||||||
|
struct switch_network_list;
|
||||||
|
typedef struct switch_network_list switch_network_list_t;
|
||||||
|
|
||||||
|
|
||||||
#define SWITCH_API_VERSION 1
|
#define SWITCH_API_VERSION 1
|
||||||
#define SWITCH_MODULE_LOAD_ARGS (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool)
|
#define SWITCH_MODULE_LOAD_ARGS (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool)
|
||||||
|
|
|
@ -84,6 +84,7 @@ SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size
|
||||||
!strcasecmp(expr, "true") ||\
|
!strcasecmp(expr, "true") ||\
|
||||||
!strcasecmp(expr, "enabled") ||\
|
!strcasecmp(expr, "enabled") ||\
|
||||||
!strcasecmp(expr, "active") ||\
|
!strcasecmp(expr, "active") ||\
|
||||||
|
!strcasecmp(expr, "allow") ||\
|
||||||
atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE
|
atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE
|
||||||
/*!
|
/*!
|
||||||
\brief find local ip of the box
|
\brief find local ip of the box
|
||||||
|
@ -347,6 +348,14 @@ SWITCH_DECLARE(char *) switch_url_decode(char *s);
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *from, const char *headers, const char *body, const char *file);
|
SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *from, const char *headers, const char *body, const char *file);
|
||||||
SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close);
|
SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close);
|
||||||
|
|
||||||
|
SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, switch_bool_t default_type, switch_memory_pool_t *pool);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok);
|
||||||
|
SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip(switch_network_list_t *list, uint32_t ip);
|
||||||
|
#define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net == _ip)
|
||||||
|
|
||||||
|
|
||||||
/* malloc or DIE macros */
|
/* malloc or DIE macros */
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define switch_malloc(ptr, len) (void)( (!!(ptr = malloc(len))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%s", __FILE__, __LINE__),abort(), 0), ptr )
|
#define switch_malloc(ptr, len) (void)( (!!(ptr = malloc(len))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%s", __FILE__, __LINE__),abort(), 0), ptr )
|
||||||
|
|
|
@ -271,6 +271,63 @@ end:
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_STANDARD_API(reload_acl_function)
|
||||||
|
{
|
||||||
|
const char *err;
|
||||||
|
switch_xml_t xml_root;
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd && !strcmp(cmd, "reloadxml")) {
|
||||||
|
if ((xml_root = switch_xml_open_root(1, &err))) {
|
||||||
|
switch_xml_free(xml_root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_load_network_lists(SWITCH_TRUE);
|
||||||
|
|
||||||
|
stream->write_function(stream, "+OK acl reloaded\n");
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_STANDARD_API(acl_function)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
char *mydata = NULL, *argv[3];
|
||||||
|
|
||||||
|
if (!cmd) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mydata = strdup(cmd);
|
||||||
|
switch_assert(mydata);
|
||||||
|
|
||||||
|
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_check_network_list_ip(argv[0], argv[1])) {
|
||||||
|
stream->write_function(stream, "true");
|
||||||
|
goto ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
stream->write_function(stream, "false");
|
||||||
|
|
||||||
|
ok:
|
||||||
|
|
||||||
|
switch_safe_free(mydata);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWITCH_STANDARD_API(regex_function)
|
SWITCH_STANDARD_API(regex_function)
|
||||||
{
|
{
|
||||||
switch_regex_t *re = NULL;
|
switch_regex_t *re = NULL;
|
||||||
|
@ -2186,6 +2243,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||||
SWITCH_ADD_API(commands_api_interface, "killchan", "Kill Channel (depricated)", kill_function, KILL_SYNTAX);
|
SWITCH_ADD_API(commands_api_interface, "killchan", "Kill Channel (depricated)", kill_function, KILL_SYNTAX);
|
||||||
SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
|
SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
|
||||||
SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
|
SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
|
||||||
|
SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload ACL", reload_acl_function, "[reloadxml]");
|
||||||
SWITCH_ADD_API(commands_api_interface, "reloadxml", "Reload XML", reload_function, "");
|
SWITCH_ADD_API(commands_api_interface, "reloadxml", "Reload XML", reload_function, "");
|
||||||
SWITCH_ADD_API(commands_api_interface, "unload", "Unload Module", unload_function, LOAD_SYNTAX);
|
SWITCH_ADD_API(commands_api_interface, "unload", "Unload Module", unload_function, LOAD_SYNTAX);
|
||||||
SWITCH_ADD_API(commands_api_interface, "load", "Load Module", load_function, LOAD_SYNTAX);
|
SWITCH_ADD_API(commands_api_interface, "load", "Load Module", load_function, LOAD_SYNTAX);
|
||||||
|
@ -2226,6 +2284,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||||
SWITCH_ADD_API(commands_api_interface, "is_lan_addr", "see if an ip is a lan addr", lan_addr_function, "<ip>");
|
SWITCH_ADD_API(commands_api_interface, "is_lan_addr", "see if an ip is a lan addr", lan_addr_function, "<ip>");
|
||||||
SWITCH_ADD_API(commands_api_interface, "cond", "Eval a conditional", cond_function, "<expr> ? <true val> : <false val>");
|
SWITCH_ADD_API(commands_api_interface, "cond", "Eval a conditional", cond_function, "<expr> ? <true val> : <false val>");
|
||||||
SWITCH_ADD_API(commands_api_interface, "regex", "Eval a regex", regex_function, "<data>|<pattern>[|<subst string>]");
|
SWITCH_ADD_API(commands_api_interface, "regex", "Eval a regex", regex_function, "<data>|<pattern>[|<subst string>]");
|
||||||
|
SWITCH_ADD_API(commands_api_interface, "acl", "compater an ip to an acl list", acl_function, "<ip> <list_name>");
|
||||||
SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX);
|
SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX);
|
||||||
SWITCH_ADD_API(commands_api_interface, "find_user_xml", "find a user", find_user_function, "<key> <user> <domain>");
|
SWITCH_ADD_API(commands_api_interface, "find_user_xml", "find a user", find_user_function, "<key> <user> <domain>");
|
||||||
SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, "<key> <user> <domain>");
|
SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, "<key> <user> <domain>");
|
||||||
|
|
|
@ -200,6 +200,28 @@ SWITCH_STANDARD_APP(send_dtmf_function)
|
||||||
switch_core_session_send_dtmf_string(session, (const char *) data);
|
switch_core_session_send_dtmf_string(session, (const char *) data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_STANDARD_APP(check_acl_function)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
char *argv[2] = { 0 };
|
||||||
|
char *mydata;
|
||||||
|
switch_call_cause_t cause = SWITCH_CAUSE_CALL_REJECTED;
|
||||||
|
|
||||||
|
if (!switch_strlen_zero(data) && (mydata = switch_core_session_strdup(session, data))) {
|
||||||
|
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) > 1) {
|
||||||
|
if (!switch_check_network_list_ip(argv[0], argv[1])) {
|
||||||
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
|
if (argc > 2) {
|
||||||
|
cause = switch_channel_str2cause(argv[2]);
|
||||||
|
}
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call failed acl check for ip %s on list %s\n", argv[0], argv[1]);
|
||||||
|
switch_channel_hangup(channel, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_STANDARD_APP(transfer_function)
|
SWITCH_STANDARD_APP(transfer_function)
|
||||||
{
|
{
|
||||||
int argc;
|
int argc;
|
||||||
|
@ -1760,6 +1782,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
||||||
SWITCH_ADD_API(api_interface, "presence", "presence", presence_api_function, "<user> <rpid> <message>");
|
SWITCH_ADD_API(api_interface, "presence", "presence", presence_api_function, "<user> <rpid> <message>");
|
||||||
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number", SAF_SUPPORT_NOMEDIA);
|
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number", SAF_SUPPORT_NOMEDIA);
|
||||||
SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]", SAF_SUPPORT_NOMEDIA);
|
SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]", SAF_SUPPORT_NOMEDIA);
|
||||||
|
SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list",
|
||||||
|
"Check an ip against an ACL list", check_acl_function, "<ip> <acl | cidr>", SAF_SUPPORT_NOMEDIA);
|
||||||
SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
|
SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
|
||||||
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
|
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
|
||||||
SWITCH_ADD_APP(app_interface, "strftime", NULL, NULL, strftime_function, NULL, SAF_SUPPORT_NOMEDIA);
|
SWITCH_ADD_APP(app_interface, "strftime", NULL, NULL, strftime_function, NULL, SAF_SUPPORT_NOMEDIA);
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include <switch_odbc.h>
|
#include <switch_odbc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SOFIA_MAX_ACL 100
|
||||||
|
|
||||||
#define MODNAME "mod_sofia"
|
#define MODNAME "mod_sofia"
|
||||||
static const switch_state_handler_table_t noop_state_handler = { 0 };
|
static const switch_state_handler_table_t noop_state_handler = { 0 };
|
||||||
struct sofia_gateway;
|
struct sofia_gateway;
|
||||||
|
@ -308,6 +310,11 @@ struct sofia_profile {
|
||||||
char *odbc_pass;
|
char *odbc_pass;
|
||||||
switch_odbc_handle_t *master_odbc;
|
switch_odbc_handle_t *master_odbc;
|
||||||
switch_queue_t *sql_queue;
|
switch_queue_t *sql_queue;
|
||||||
|
char *acl[SOFIA_MAX_ACL];
|
||||||
|
uint32_t acl_count;
|
||||||
|
char *reg_acl[SOFIA_MAX_ACL];
|
||||||
|
uint32_t reg_acl_count;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct private_object {
|
struct private_object {
|
||||||
|
|
|
@ -1195,6 +1195,18 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||||
profile->username = switch_core_strdup(profile->pool, val);
|
profile->username = switch_core_strdup(profile->pool, val);
|
||||||
} else if (!strcasecmp(var, "context")) {
|
} else if (!strcasecmp(var, "context")) {
|
||||||
profile->context = switch_core_strdup(profile->pool, val);
|
profile->context = switch_core_strdup(profile->pool, val);
|
||||||
|
} else if (!strcasecmp(var, "apply-inbound-acl")) {
|
||||||
|
if (profile->acl_count < SOFIA_MAX_ACL) {
|
||||||
|
profile->acl[profile->acl_count++] = switch_core_strdup(profile->pool, val);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
|
||||||
|
}
|
||||||
|
} else if (!strcasecmp(var, "apply-register-acl")) {
|
||||||
|
if (profile->reg_acl_count < SOFIA_MAX_ACL) {
|
||||||
|
profile->reg_acl[profile->reg_acl_count++] = switch_core_strdup(profile->pool, val);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
|
||||||
|
}
|
||||||
} else if (!strcasecmp(var, "alias")) {
|
} else if (!strcasecmp(var, "alias")) {
|
||||||
sip_alias_node_t *node;
|
sip_alias_node_t *node;
|
||||||
if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
|
if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
|
||||||
|
@ -2478,6 +2490,18 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
|
||||||
|
|
||||||
get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
|
get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
|
||||||
|
|
||||||
|
if (profile->acl_count) {
|
||||||
|
int x = 0;
|
||||||
|
for (x = 0 ; x < profile->acl_count; x++) {
|
||||||
|
if (!switch_check_network_list_ip(network_ip, profile->acl[x])) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", network_ip, profile->acl[x]);
|
||||||
|
nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((profile->pflags & PFLAG_AUTH_CALLS) || (!(profile->pflags & PFLAG_BLIND_AUTH) && (sip->sip_proxy_authorization || sip->sip_authorization))) {
|
if ((profile->pflags & PFLAG_AUTH_CALLS) || (!(profile->pflags & PFLAG_BLIND_AUTH) && (sip->sip_proxy_authorization || sip->sip_authorization))) {
|
||||||
if (strcmp(network_ip, profile->sipip)) {
|
if (strcmp(network_ip, profile->sipip)) {
|
||||||
if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event)) {
|
if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event)) {
|
||||||
|
|
|
@ -655,6 +655,23 @@ void sofia_reg_handle_sip_i_register(nua_t * nua, sofia_profile_t *profile, nua_
|
||||||
{
|
{
|
||||||
char key[128] = "";
|
char key[128] = "";
|
||||||
switch_event_t *v_event = NULL;
|
switch_event_t *v_event = NULL;
|
||||||
|
char network_ip[80];
|
||||||
|
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
|
||||||
|
|
||||||
|
if (profile->reg_acl_count) {
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
|
||||||
|
|
||||||
|
for (x = 0 ; x < profile->reg_acl_count; x++) {
|
||||||
|
if (!switch_check_network_list_ip(network_ip, profile->reg_acl[x])) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", network_ip, profile->reg_acl[x]);
|
||||||
|
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!(profile->mflags & MFLAG_REGISTER)) {
|
if (!(profile->mflags & MFLAG_REGISTER)) {
|
||||||
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
|
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
|
||||||
|
|
|
@ -71,6 +71,9 @@ struct listener {
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
int lost_events;
|
int lost_events;
|
||||||
int lost_logs;
|
int lost_logs;
|
||||||
|
switch_sockaddr_t *sa;
|
||||||
|
char remote_ip[50];
|
||||||
|
switch_port_t remote_port;
|
||||||
struct listener *next;
|
struct listener *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,6 +87,8 @@ static struct {
|
||||||
uint8_t ready;
|
uint8_t ready;
|
||||||
} listen_list;
|
} listen_list;
|
||||||
|
|
||||||
|
#define MAX_ACL 100
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
switch_mutex_t *mutex;
|
switch_mutex_t *mutex;
|
||||||
char *ip;
|
char *ip;
|
||||||
|
@ -91,6 +96,8 @@ static struct {
|
||||||
char *password;
|
char *password;
|
||||||
int done;
|
int done;
|
||||||
int threads;
|
int threads;
|
||||||
|
char *acl[MAX_ACL];
|
||||||
|
uint32_t acl_count;
|
||||||
} prefs;
|
} prefs;
|
||||||
|
|
||||||
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip);
|
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip);
|
||||||
|
@ -1052,18 +1059,44 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t * thread, void *obj
|
||||||
switch_core_session_t *session = NULL;
|
switch_core_session_t *session = NULL;
|
||||||
switch_channel_t *channel = NULL;
|
switch_channel_t *channel = NULL;
|
||||||
|
|
||||||
|
|
||||||
switch_mutex_lock(listen_list.mutex);
|
switch_mutex_lock(listen_list.mutex);
|
||||||
prefs.threads++;
|
prefs.threads++;
|
||||||
switch_mutex_unlock(listen_list.mutex);
|
switch_mutex_unlock(listen_list.mutex);
|
||||||
|
|
||||||
switch_assert(listener != NULL);
|
switch_assert(listener != NULL);
|
||||||
|
|
||||||
|
if (prefs.acl_count && listener->sa && !switch_strlen_zero(listener->remote_ip)) {
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
for (x = 0 ; x < prefs.acl_count; x++) {
|
||||||
|
if (!switch_check_network_list_ip(listener->remote_ip, prefs.acl[x])) {
|
||||||
|
const char message[] = "Access Denied, go away.\n";
|
||||||
|
int mlen = strlen(message);
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", listener->remote_ip, prefs.acl[x]);
|
||||||
|
|
||||||
|
switch_snprintf(buf, sizeof(buf), "Content-Type: rude/rejection\nContent-Length %d\n\n", mlen);
|
||||||
|
len = strlen(buf);
|
||||||
|
switch_socket_send(listener->sock, buf, &len);
|
||||||
|
len = mlen;
|
||||||
|
switch_socket_send(listener->sock, message, &len);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((session = listener->session)) {
|
if ((session = listener->session)) {
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
switch_core_session_read_lock(session);
|
switch_core_session_read_lock(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (switch_strlen_zero(listener->remote_ip)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open from %s:%d\n", listener->remote_ip, listener->remote_port);
|
||||||
|
}
|
||||||
|
|
||||||
switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK, TRUE);
|
switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK, TRUE);
|
||||||
switch_set_flag_locked(listener, LFLAG_RUNNING);
|
switch_set_flag_locked(listener, LFLAG_RUNNING);
|
||||||
|
@ -1230,6 +1263,12 @@ static int config(void)
|
||||||
prefs.port = (uint16_t) atoi(val);
|
prefs.port = (uint16_t) atoi(val);
|
||||||
} else if (!strcmp(var, "password")) {
|
} else if (!strcmp(var, "password")) {
|
||||||
set_pref_pass(val);
|
set_pref_pass(val);
|
||||||
|
} else if (!strcasecmp(var, "apply-inbound-acl")) {
|
||||||
|
if (prefs.acl_count < MAX_ACL) {
|
||||||
|
prefs.acl[prefs.acl_count++] = strdup(val);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", MAX_ACL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1259,6 +1298,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
|
||||||
switch_sockaddr_t *sa;
|
switch_sockaddr_t *sa;
|
||||||
switch_socket_t *inbound_socket = NULL;
|
switch_socket_t *inbound_socket = NULL;
|
||||||
listener_t *listener;
|
listener_t *listener;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
memset(&listen_list, 0, sizeof(listen_list));
|
memset(&listen_list, 0, sizeof(listen_list));
|
||||||
config();
|
config();
|
||||||
|
@ -1335,6 +1375,9 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
|
||||||
listener->format = EVENT_FORMAT_PLAIN;
|
listener->format = EVENT_FORMAT_PLAIN;
|
||||||
switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
|
switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
|
||||||
switch_core_hash_init(&listener->event_hash, listener->pool);
|
switch_core_hash_init(&listener->event_hash, listener->pool);
|
||||||
|
switch_socket_addr_get(&listener->sa, SWITCH_TRUE, listener->sock);
|
||||||
|
switch_get_addr(listener->remote_ip, sizeof(listener->remote_ip), listener->sa);
|
||||||
|
listener->remote_port = switch_sockaddr_get_port(listener->sa);
|
||||||
launch_listener_thread(listener);
|
launch_listener_thread(listener);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1349,6 +1392,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
|
||||||
switch_core_destroy_memory_pool(&listener_pool);
|
switch_core_destroy_memory_pool(&listener_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (x = 0 ; x < prefs.acl_count; x++) {
|
||||||
|
switch_safe_free(prefs.acl[x]);
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,6 +521,11 @@ SWITCH_DECLARE(switch_status_t) switch_thread_create(switch_thread_t ** new_thre
|
||||||
|
|
||||||
/* socket stubs */
|
/* socket stubs */
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t **sa, switch_bool_t remote, switch_socket_t *sock)
|
||||||
|
{
|
||||||
|
return apr_socket_addr_get(sa, remote, sock);
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_socket_create(switch_socket_t ** new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
|
SWITCH_DECLARE(switch_status_t) switch_socket_create(switch_socket_t ** new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
|
||||||
{
|
{
|
||||||
return apr_socket_create(new_sock, family, type, protocol, pool);
|
return apr_socket_create(new_sock, family, type, protocol, pool);
|
||||||
|
|
|
@ -686,6 +686,132 @@ SWITCH_DECLARE(void) switch_core_setrlimits(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
switch_hash_t *hash;
|
||||||
|
} switch_ip_list_t;
|
||||||
|
|
||||||
|
static switch_ip_list_t IP_LIST = { 0 };
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip(const char *ip_str, const char *list_name)
|
||||||
|
{
|
||||||
|
switch_network_list_t *list;
|
||||||
|
uint32_t ip, net, mask, bits;
|
||||||
|
switch_bool_t ok = SWITCH_FALSE;
|
||||||
|
|
||||||
|
switch_mutex_lock(runtime.global_mutex);
|
||||||
|
inet_pton(AF_INET, ip_str, &ip);
|
||||||
|
|
||||||
|
if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
|
||||||
|
ok = switch_network_list_validate_ip(list, ip);
|
||||||
|
} else if (strchr(list_name, '/')) {
|
||||||
|
switch_parse_cidr(list_name, &net, &mask, &bits);
|
||||||
|
ok = switch_test_subnet(ip, net, mask);
|
||||||
|
}
|
||||||
|
switch_mutex_unlock(runtime.global_mutex);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
|
||||||
|
{
|
||||||
|
switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;
|
||||||
|
switch_network_list_t *list;
|
||||||
|
|
||||||
|
|
||||||
|
switch_mutex_lock(runtime.global_mutex);
|
||||||
|
|
||||||
|
if (IP_LIST.hash) {
|
||||||
|
switch_core_hash_destroy(&IP_LIST.hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IP_LIST.pool) {
|
||||||
|
switch_core_destroy_memory_pool(&IP_LIST.pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&IP_LIST, 0, sizeof(IP_LIST));
|
||||||
|
switch_core_new_memory_pool(&IP_LIST.pool);
|
||||||
|
switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool);
|
||||||
|
|
||||||
|
if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {
|
||||||
|
if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
|
||||||
|
for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
|
||||||
|
const char *name = switch_xml_attr(x_list, "name");
|
||||||
|
const char *dft = switch_xml_attr(x_list, "default");
|
||||||
|
switch_bool_t default_type = SWITCH_TRUE;
|
||||||
|
|
||||||
|
if (switch_strlen_zero(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dft) {
|
||||||
|
default_type = switch_true(dft);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_network_list_create(&list, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reload) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
|
||||||
|
const char *cidr = NULL, *host = NULL, *mask = NULL;
|
||||||
|
switch_bool_t ok = default_type;
|
||||||
|
const char *type = switch_xml_attr(x_node, "type");
|
||||||
|
|
||||||
|
if (type) {
|
||||||
|
ok = switch_true(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
cidr = switch_xml_attr(x_node, "cidr");
|
||||||
|
host = switch_xml_attr(x_node, "host");
|
||||||
|
mask = switch_xml_attr(x_node, "mask");
|
||||||
|
|
||||||
|
if (cidr) {
|
||||||
|
if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (reload) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (reload) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||||
|
"Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
|
||||||
|
"Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (host && mask) {
|
||||||
|
if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (reload) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
|
||||||
|
"Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
|
||||||
|
"Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_hash_insert(IP_LIST.hash, name, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_xml_free(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(runtime.global_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
|
SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
|
||||||
{
|
{
|
||||||
switch_xml_t xml = NULL, cfg = NULL;
|
switch_xml_t xml = NULL, cfg = NULL;
|
||||||
|
@ -795,6 +921,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
|
||||||
switch_core_hash_insert(runtime.global_vars, varr, vall);
|
switch_core_hash_insert(runtime.global_vars, varr, vall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_xml_free(xml);
|
switch_xml_free(xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,6 +1041,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signal(SIGHUP, handle_SIGHUP);
|
signal(SIGHUP, handle_SIGHUP);
|
||||||
|
switch_load_network_lists(SWITCH_FALSE);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
|
||||||
|
|
|
@ -38,6 +38,138 @@
|
||||||
#include "private/switch_core_pvt.h"
|
#include "private/switch_core_pvt.h"
|
||||||
#define ESCAPE_META '\\'
|
#define ESCAPE_META '\\'
|
||||||
|
|
||||||
|
struct switch_network_node {
|
||||||
|
uint32_t ip;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t bits;
|
||||||
|
switch_bool_t ok;
|
||||||
|
struct switch_network_node *next;
|
||||||
|
};
|
||||||
|
typedef struct switch_network_node switch_network_node_t;
|
||||||
|
|
||||||
|
struct switch_network_list {
|
||||||
|
struct switch_network_node *node_head;
|
||||||
|
switch_bool_t default_type;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, switch_bool_t default_type, switch_memory_pool_t *pool)
|
||||||
|
{
|
||||||
|
switch_network_list_t *new_list;
|
||||||
|
|
||||||
|
if (!pool) {
|
||||||
|
switch_core_new_memory_pool(&pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_list = switch_core_alloc(pool, sizeof(**list));
|
||||||
|
new_list->pool = pool;
|
||||||
|
new_list->default_type = default_type;
|
||||||
|
|
||||||
|
*list = new_list;
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip(switch_network_list_t *list, uint32_t ip)
|
||||||
|
{
|
||||||
|
switch_network_node_t *node;
|
||||||
|
switch_bool_t ok = list->default_type;
|
||||||
|
uint32_t bits = 0;
|
||||||
|
|
||||||
|
for (node = list->node_head; node; node = node->next) {
|
||||||
|
if (node->bits > bits && switch_test_subnet(ip, node->ip, node->mask)) {
|
||||||
|
if (node->ok) {
|
||||||
|
ok = SWITCH_TRUE;
|
||||||
|
} else {
|
||||||
|
ok = SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
bits = node->bits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok)
|
||||||
|
{
|
||||||
|
uint32_t ip, mask, bits;
|
||||||
|
switch_network_node_t *node;
|
||||||
|
|
||||||
|
if (switch_parse_cidr(cidr_str, &ip, &mask, &bits)) {
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = switch_core_alloc(list->pool, sizeof(*node));
|
||||||
|
|
||||||
|
node->ip = ip;
|
||||||
|
node->mask = mask;
|
||||||
|
node->ok = ok;
|
||||||
|
node->bits = bits;
|
||||||
|
|
||||||
|
node->next = list->node_head;
|
||||||
|
list->node_head = node;
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok)
|
||||||
|
{
|
||||||
|
int ip, mask;
|
||||||
|
switch_network_node_t *node;
|
||||||
|
|
||||||
|
inet_pton(AF_INET, host, &ip);
|
||||||
|
inet_pton(AF_INET, mask_str, &mask);
|
||||||
|
|
||||||
|
node = switch_core_alloc(list->pool, sizeof(*node));
|
||||||
|
|
||||||
|
node->ip = ip;
|
||||||
|
node->mask = mask;
|
||||||
|
node->ok = ok;
|
||||||
|
|
||||||
|
/* http://graphics.stanford.edu/~seander/bithacks.html */
|
||||||
|
mask = mask - ((mask >> 1) & 0x55555555);
|
||||||
|
mask = (mask & 0x33333333) + ((mask >> 2) & 0x33333333);
|
||||||
|
node->bits = (((mask + (mask >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||||
|
|
||||||
|
node->next = list->node_head;
|
||||||
|
list->node_head = node;
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp)
|
||||||
|
{
|
||||||
|
char host[128] = "";
|
||||||
|
char *bit_str;
|
||||||
|
int32_t bits;
|
||||||
|
|
||||||
|
strncpy(host, string, sizeof(host) - 1);
|
||||||
|
bit_str = strchr(host, '/');
|
||||||
|
|
||||||
|
if (!bit_str) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bit_str++ = '\0';
|
||||||
|
bits = atoi(bit_str);
|
||||||
|
|
||||||
|
if (bits < 0 || bits > 32) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = atoi(bit_str);
|
||||||
|
inet_pton(AF_INET, host, ip);
|
||||||
|
*mask = 0xFFFFFFFF & ~(0xFFFFFFFF << bits);
|
||||||
|
*bitp = bits;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close)
|
SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close)
|
||||||
{
|
{
|
||||||
const char *e = NULL;
|
const char *e = NULL;
|
||||||
|
|
Loading…
Reference in New Issue