diff --git a/conf/autoload_configs/acl.conf.xml b/conf/autoload_configs/acl.conf.xml index 73f78a625f..655e2facf3 100644 --- a/conf/autoload_configs/acl.conf.xml +++ b/conf/autoload_configs/acl.conf.xml @@ -1,26 +1,18 @@ <configuration name="acl.conf" description="Network Lists"> <network-lists> + <!-- + These ACL's are automatically created on startup. - <list name="dl-candidates" default="allow"> - <node type="deny" cidr="10.0.0.0/8"/> - <node type="deny" cidr="172.16.0.0/12"/> - <node type="deny" cidr="192.168.0.0/16"/> - </list> - - <list name="rfc1918" default="deny"> - <node type="allow" cidr="10.0.0.0/8"/> - <node type="allow" cidr="172.16.0.0/12"/> - <node type="allow" cidr="192.168.0.0/16"/> - </list> + rfc1918.auto - RFC1918 Space + nat.auto - RFC1918 Minus your local lan. + localnet.auto - ACL for your local lan. + --> <list name="lan" default="allow"> <node type="deny" cidr="192.168.42.0/24"/> <node type="allow" cidr="192.168.42.42/32"/> </list> - <list name="strict" default="deny"> - <node type="allow" cidr="208.102.123.124/32"/> - </list> <!-- This will traverse the directory adding all users with the cidr= tag to this ACL, when this ACL matches diff --git a/conf/jingle_profiles/client.xml b/conf/jingle_profiles/client.xml index f608dd2021..e527c19154 100644 --- a/conf/jingle_profiles/client.xml +++ b/conf/jingle_profiles/client.xml @@ -26,6 +26,6 @@ <!-- <param name="vad" value="out"/> --> <param name="vad" value="both"/> <!--<param name="avatar" value="/path/to/tiny.jpg"/>--> - <!--<param name="candidate-acl" value="dl-candidates"/>--> + <!--<param name="candidate-acl" value="rfc1918.auto"/>--> </x-profile> </include> diff --git a/conf/jingle_profiles/server.xml b/conf/jingle_profiles/server.xml index 9d1533a6e2..9fcd641237 100644 --- a/conf/jingle_profiles/server.xml +++ b/conf/jingle_profiles/server.xml @@ -16,6 +16,6 @@ <!--<param name="avatar" value="/path/to/tiny.jpg"/>--> <!--If you have ODBC support and a working dsn you can use it instead of SQLite--> <!--<param name="odbc-dsn" value="dsn:user:pass"/>--> - <!--<param name="candidate-acl" value="dl-candidates"/>--> + <!--<param name="candidate-acl" value="rfc1918.auto"/>--> </x-profile> </include> diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 90edf4b172..9a818c8eb2 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -232,7 +232,8 @@ typedef enum { SCF_CRASH_PROT = (1 << 3), SCF_VG = (1 << 4), SCF_RESTART = (1 << 5), - SCF_SHUTDOWN_REQUESTED = (1 << 6) + SCF_SHUTDOWN_REQUESTED = (1 << 6), + SCF_USE_AUTO_NAT = (1 << 7) } switch_core_flag_enum_t; typedef uint32_t switch_core_flag_t; diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 466bc22541..9daf28db01 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -172,7 +172,7 @@ SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame); \return SWITCH_STATUS_SUCCESSS for success, otherwise failure */ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(_Out_opt_bytecapcount_(len) - char *buf, _In_ int len, _In_ int family); + char *buf, _In_ int len, _In_ int *mask, _In_ int family); /*! \brief find the char representation of an ip adress @@ -550,7 +550,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *fr 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_create(switch_network_list_t **list, const char *name, switch_bool_t default_type, switch_memory_pool_t *pool); SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token); #define switch_network_list_add_cidr(_list, _cidr_str, _ok) switch_network_list_add_cidr_token(_list, _cidr_str, _ok, NULL) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index b5989b1213..98f3df894f 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -608,7 +608,7 @@ SWITCH_STANDARD_API(stun_function) if (pip) { switch_copy_string(ip_buf, pip, sizeof(ip_buf)); } else { - switch_find_local_ip(ip_buf, sizeof(ip_buf), AF_INET); + switch_find_local_ip(ip_buf, sizeof(ip_buf), NULL, AF_INET); } switch_core_new_memory_pool(&pool); diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index 71abfd8c7b..e3c89c5fb1 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -172,7 +172,7 @@ SWITCH_STANDARD_APP(bcast_function) if ((var = switch_channel_get_variable(channel, "esf_broadcast_ip"))) { esf_broadcast_ip = switch_core_session_strdup(session, var); } else { - switch_find_local_ip(guess_ip, sizeof(guess_ip), AF_INET); + switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET); esf_broadcast_ip = guess_ip; } diff --git a/src/mod/endpoints/mod_alsa/mod_alsa.c b/src/mod/endpoints/mod_alsa/mod_alsa.c index e7431252e4..1768f30b00 100644 --- a/src/mod/endpoints/mod_alsa/mod_alsa.c +++ b/src/mod/endpoints/mod_alsa/mod_alsa.c @@ -1484,7 +1484,7 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t tech_pvt->codec_ms = atoi(argv[5]); } - switch_find_local_ip(ip, sizeof(ip), AF_INET); + switch_find_local_ip(ip, sizeof(ip), NULL, AF_INET); if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), NULL, diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 9560c16ad3..930d0d9593 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -2215,7 +2215,7 @@ static switch_status_t load_config(void) memset(&globals, 0, sizeof(globals)); globals.running = 1; - switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), AF_INET); + switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), NULL, AF_INET); switch_core_hash_init(&globals.profile_hash, module_pool); diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index b6936e6704..8b06e1e7aa 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -1755,7 +1755,7 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t tech_pvt->codec_ms = atoi(argv[5]); } - switch_find_local_ip(ip, sizeof(ip), AF_INET); + switch_find_local_ip(ip, sizeof(ip), NULL, AF_INET); if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), NULL, dialplan, cid_name, cid_num, ip, NULL, NULL, NULL, modname, NULL, dest)) != 0) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 605a0d7c12..d8e87d3be0 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3204,7 +3204,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) mod_sofia_globals.pool = pool; switch_mutex_init(&mod_sofia_globals.mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool); - switch_find_local_ip(mod_sofia_globals.guess_ip, sizeof(mod_sofia_globals.guess_ip), AF_INET); + switch_find_local_ip(mod_sofia_globals.guess_ip, sizeof(mod_sofia_globals.guess_ip), &mod_sofia_globals.guess_mask, AF_INET); + switch_set_string(mod_sofia_globals.guess_mask_str, inet_ntoa(*(struct in_addr *)&mod_sofia_globals.guess_mask)); gethostname(mod_sofia_globals.hostname, sizeof(mod_sofia_globals.hostname)); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 5143e0a93d..fe08c7772f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -268,6 +268,8 @@ struct mod_sofia_globals { switch_event_node_t *roster_node; switch_event_node_t *custom_node; switch_event_node_t *mwi_node; + int guess_mask; + char guess_mask_str[16]; int debug_presence; int auto_restart; }; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 9ada7ebf67..0ab2723832 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -627,7 +627,7 @@ void event_handler(switch_event_t *event) switch_mutex_lock(profile->ireg_mutex); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); - switch_find_local_ip(guess_ip4, sizeof(guess_ip4), AF_INET); + switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET); sql = switch_mprintf("insert into sip_registrations " "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires," "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm) " diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 22b5c2f2e1..d9c721368f 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1045,7 +1045,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_mutex_lock(profile->ireg_mutex); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); - switch_find_local_ip(guess_ip4, sizeof(guess_ip4), AF_INET); + switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET); sql = switch_mprintf("insert into sip_registrations " "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires," "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm) " diff --git a/src/switch.c b/src/switch.c index 90a42e62bc..c238b59276 100644 --- a/src/switch.c +++ b/src/switch.c @@ -171,7 +171,7 @@ void WINAPI ServiceCtrlHandler(DWORD control) /* the main service entry point */ void WINAPI service_main(DWORD numArgs, char **args) { - switch_core_flag_t flags = SCF_USE_SQL; + switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT; const char *err = NULL; /* error value for return from freeswitch initialization */ /* we have to initialize the service-specific stuff */ memset(&status, 0, sizeof(SERVICE_STATUS)); @@ -274,7 +274,7 @@ int main(int argc, char *argv[]) int alt_dirs = 0; int known_opt; int high_prio = 0; - switch_core_flag_t flags = SCF_USE_SQL; + switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT; int ret = 0; switch_status_t destroy_status; switch_file_t *fd; @@ -306,6 +306,7 @@ int main(int argc, char *argv[]) "\t-hp -- enable high priority settings\n" "\t-vg -- run under valgrind\n" "\t-nosql -- disable internal sql scoreboard\n" + "\t-nonat -- disable auto nat detection\n" "\t-stop -- stop freeswitch\n" "\t-nc -- do not output to a console and background\n" "\t-c -- output to a console and stay in the foreground\n" @@ -463,6 +464,11 @@ int main(int argc, char *argv[]) known_opt++; } + if (argv[x] && !strcmp(argv[x], "-nonat")) { + flags &= ~SCF_USE_AUTO_NAT; + known_opt++; + } + if (argv[x] && !strcmp(argv[x], "-vg")) { flags |= SCF_VG; known_opt++; diff --git a/src/switch_core.c b/src/switch_core.c index 19d9257fd6..8a24644732 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -95,9 +95,10 @@ static void check_ip(void) { char old_ip4[256] = ""; char old_ip6[256] = ""; int ok4 = 1, ok6 = 1; - - switch_find_local_ip(guess_ip4, sizeof(guess_ip4), AF_INET); - switch_find_local_ip(guess_ip6, sizeof(guess_ip6), AF_INET6); + int mask = 0; + + switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET); + switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6); if (!*main_ip4) { switch_set_string(main_ip4, guess_ip4); @@ -106,6 +107,7 @@ static void check_ip(void) { switch_set_string(old_ip4, main_ip4); switch_set_string(main_ip4, guess_ip4); switch_core_set_variable("local_ip_v4", guess_ip4); + switch_core_set_variable("local_mask_v4", inet_ntoa(*(struct in_addr *)&mask)); } } @@ -861,9 +863,16 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_ 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_network_list_t *rfc_list, *list; + char guess_ip[16] = ""; + int mask = 0; + char guess_mask[16] = ""; + char *tmp_name; + int ip_tmp = 0; + switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); + switch_set_string(guess_mask, inet_ntoa(*(struct in_addr *)&mask)); + switch_mutex_lock(runtime.global_mutex); if (IP_LIST.hash) { @@ -878,6 +887,44 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) switch_core_new_memory_pool(&IP_LIST.pool); switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool); + + tmp_name = "rfc1918.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "nat.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "localnet.auto"; + switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + + if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, + "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name); + } + switch_core_hash_insert(IP_LIST.hash, tmp_name, list); + + switch_inet_pton(AF_INET, guess_ip, &ip_tmp); + ip_tmp = htonl(ip_tmp); + tmp_name = "nat.auto"; + + if (switch_network_list_validate_ip_token(rfc_list, ip_tmp, NULL)) { + switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, + "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name); + } + + 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) { @@ -893,7 +940,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) default_type = switch_true(dft); } - if (switch_network_list_create(&list, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) { + if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) { abort(); } @@ -1075,6 +1122,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc switch_uuid_t uuid; char guess_ip[256]; char *dir_path; + int mask = 0; memset(&runtime, 0, sizeof(runtime)); @@ -1128,16 +1176,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.flags = flags; runtime.sps_total = 30; - switch_find_local_ip(guess_ip, sizeof(guess_ip), AF_INET); + switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); switch_core_set_variable("local_ip_v4", guess_ip); - switch_find_local_ip(guess_ip, sizeof(guess_ip), AF_INET6); + switch_core_set_variable("local_mask_v4", inet_ntoa(*(struct in_addr *)&mask)); + + + switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6); switch_core_set_variable("local_ip_v6", guess_ip); switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir); switch_core_set_serial(); switch_event_init(runtime.memory_pool); - switch_nat_init(runtime.memory_pool); + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { + switch_nat_init(runtime.memory_pool); + } if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) { apr_terminate(); @@ -1559,7 +1612,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_scheduler_task_thread_stop(); switch_rtp_shutdown(); - switch_nat_shutdown(); + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { + switch_nat_shutdown(); + } switch_xml_destroy(); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n"); diff --git a/src/switch_event.c b/src/switch_event.c index 3f8ae1afcd..b815b5894a 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -574,8 +574,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) switch_threadattr_create(&thd_attr, pool); gethostname(hostname, sizeof(hostname)); - switch_find_local_ip(guess_ip_v4, sizeof(guess_ip_v4), AF_INET); - switch_find_local_ip(guess_ip_v6, sizeof(guess_ip_v6), AF_INET6); + switch_find_local_ip(guess_ip_v4, sizeof(guess_ip_v4), NULL, AF_INET); + switch_find_local_ip(guess_ip_v6, sizeof(guess_ip_v6), NULL, AF_INET6); switch_queue_create(&EVENT_QUEUE[0], POOL_COUNT_MAX + 10, THRUNTIME_POOL); diff --git a/src/switch_nat.c b/src/switch_nat.c index 990085a6ff..1b9d3cab63 100644 --- a/src/switch_nat.c +++ b/src/switch_nat.c @@ -144,7 +144,7 @@ SWITCH_DECLARE(void) switch_nat_init(switch_memory_pool_t *pool) memset(&nat_globals, 0, sizeof(nat_globals)); nat_globals.pool = pool; - switch_find_local_ip(nat_globals.pvt_addr, sizeof(nat_globals.pvt_addr), AF_INET); + switch_find_local_ip(nat_globals.pvt_addr, sizeof(nat_globals.pvt_addr), NULL, AF_INET); init_pmp(); diff --git a/src/switch_utils.c b/src/switch_utils.c index 4d745f3407..505c85cbd5 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -44,6 +44,7 @@ struct switch_network_node { uint32_t bits; switch_bool_t ok; char *token; + char *str; struct switch_network_node *next; }; typedef struct switch_network_node switch_network_node_t; @@ -52,6 +53,7 @@ struct switch_network_list { struct switch_network_node *node_head; switch_bool_t default_type; switch_memory_pool_t *pool; + char *name; }; #ifndef WIN32 @@ -119,7 +121,7 @@ SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame) return SWITCH_STATUS_SUCCESS; } -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_create(switch_network_list_t **list, const char *name, switch_bool_t default_type, switch_memory_pool_t *pool) { switch_network_list_t *new_list; @@ -130,6 +132,7 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t new_list = switch_core_alloc(pool, sizeof(**list)); new_list->pool = pool; new_list->default_type = default_type; + new_list->name = switch_core_strdup(new_list->pool, name); *list = new_list; @@ -176,6 +179,7 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_networ node->mask = mask; node->ok = ok; node->bits = bits; + node->str = switch_core_strdup(list->pool, cidr_str); if (!switch_strlen_zero(token)) { node->token = switch_core_strdup(list->pool, token); @@ -197,15 +201,16 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network node = switch_core_alloc(list->pool, sizeof(*node)); - node->ip = ip; - node->mask = mask; + node->ip = ntohl(ip); + node->mask = ntohl(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->str = switch_core_sprintf(list->pool, "%s:%s", host, mask_str); + node->next = list->node_head; list->node_head = node; @@ -735,7 +740,33 @@ SWITCH_DECLARE(const char *) switch_stristr(const char *instr, const char *str) return NULL; } -SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int family) +#ifndef WIN32 +#include <ifaddrs.h> + +static int get_netmask(struct sockaddr_in *me, int *mask) +{ + struct ifaddrs *ifaddrs, *i = NULL; + + if (getifaddrs(&ifaddrs) < 0) { + return -1; + } + + for(i = ifaddrs; i; i = i->ifa_next) { + struct sockaddr_in *s = (struct sockaddr_in *)i->ifa_addr; + struct sockaddr_in *m = (struct sockaddr_in *)i->ifa_netmask; + + if (s->sin_addr.s_addr == me->sin_addr.s_addr) { + *mask = m->sin_addr.s_addr; + return 0; + } + } + + + return -2; +} +#endif + +SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *mask, int family) { switch_status_t status = SWITCH_STATUS_FALSE; char *base; @@ -758,7 +789,6 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int fam if (len < 16) { return status; } - switch (family) { case AF_INET: @@ -790,6 +820,10 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int fam return status; } + if (mask) { + *mask = 0; // find the right one + } + closesocket(tmp_socket); freeaddrinfo(address_info); @@ -832,6 +866,10 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int fam } switch_copy_string(buf, get_addr(abuf, sizeof(abuf), (struct sockaddr*)&iface_out, sizeof(iface_out)), len); + if (mask) { + get_netmask((struct sockaddr_in*)&iface_out, mask); + } + status = SWITCH_STATUS_SUCCESS; } break;