]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add netmask detection for nat discovery work
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 2 Jun 2009 16:55:10 +0000 (16:55 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 2 Jun 2009 16:55:10 +0000 (16:55 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13549 d0543943-73ff-0310-b7d9-9358b9ac24b2

19 files changed:
conf/autoload_configs/acl.conf.xml
conf/jingle_profiles/client.xml
conf/jingle_profiles/server.xml
src/include/switch_types.h
src/include/switch_utils.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/applications/mod_esf/mod_esf.c
src/mod/endpoints/mod_alsa/mod_alsa.c
src/mod/endpoints/mod_dingaling/mod_dingaling.c
src/mod/endpoints/mod_portaudio/mod_portaudio.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_reg.c
src/switch.c
src/switch_core.c
src/switch_event.c
src/switch_nat.c
src/switch_utils.c

index 73f78a625fcb23b026722f81266aea3fd4da3038..655e2facf3a078a5b42815182b16172b9d611181 100644 (file)
@@ -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
index f608dd202195b1a24b780a9678ccfa909ede3b17..e527c19154b20a91e000a13a8e923d60aefbc6e7 100644 (file)
@@ -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>
index 9d1533a6e293c1a161dfe6114b57da77c6ab6f35..9fcd6412377d246b9f256c17915e6973ff9ae500 100644 (file)
@@ -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>
index 90edf4b17296d6df42ff75bb6565712e0f06ef4c..9a818c8eb2988650b79392f1ae9ab3b66bcdc9e4 100644 (file)
@@ -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;
 
index 466bc22541962d9ea79371c359506b714b37809a..9daf28db01b5c20b2e44b73e4d97008d059df220 100644 (file)
@@ -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)
 
index b5989b1213d19e47ef56e0122ab4f46523732e31..98f3df894f8d8ac291d3512a77e47a548335cf72 100644 (file)
@@ -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);
index 71abfd8c7b91fc9e8817e1400b3394571754d9cb..e3c89c5fb114df6c9867e784e1043657d69ec2a0 100644 (file)
@@ -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;
                }
 
index e7431252e41836b800374ae13232e3d68d9151a8..1768f30b00bf53e9a1dc4197bbfe1985adfb41c8 100644 (file)
@@ -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,
index 9560c16ad3672587737ddfa0ea9de9fdd300900c..930d0d95933b5422faf9366d892d1645bd3a30a8 100644 (file)
@@ -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);
 
index b6936e6704ecc9212c82cd5fde166ed694d66d25..8b06e1e7aa2a0b8d70fffca8a2010e13296802b6 100644 (file)
@@ -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) {
index 605a0d7c12640a84dcf6d166e447332ab181293d..d8e87d3be0a38e9fd6847e992b8495982cb68eb4 100644 (file)
@@ -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));
 
 
index 5143e0a93d3d03099186caf720dedaeb1f77e4db..fe08c7772fa74f4e45bfecc9f8612b0b42d08f47 100644 (file)
@@ -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;
 };
index 9ada7ebf678d513720cdc0a675e83d5fae0d5b33..0ab272383289a455f2b6291fa9727d2649d29d0a 100644 (file)
@@ -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) "
index 22b5c2f2e1b54a1ed6094b09cc2d83119ec88dfe..d9c721368fa46e82fc8140564541f9ce28e38dee 100644 (file)
@@ -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) "
index 90a42e62bc74a74cf9c283b093f89066878eb6ce..c238b5927685d6c3e6660ab382d0bbf43fbe0d08 100644 (file)
@@ -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++;
index 19d9257fd6cecf1402888457a73ec510eb8ca61f..8a2464473250fd97dabd8b0d70d6fe64f389792b 100644 (file)
@@ -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");
index 3f8ae1afcd31fca7ef0c499a04e1e1a69aaecc2d..b815b5894a55fcb0264b162502c299c93cf11293 100644 (file)
@@ -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);
index 990085a6ff19122d3212703ac9eb045ec6f2ddf8..1b9d3cab63c47913e87a229def768b122842fda7 100644 (file)
@@ -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();
 
index 4d745f340775adca71916830edea7d544792ddf7..505c85cbd5f4ba03374416fa9c789c8fd7dd5809 100644 (file)
@@ -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;