From db91f0e81ff9cd6705f51dd58582d393aeeae267 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 15 Nov 2010 11:37:07 -0600 Subject: [PATCH] FS-2842: ACL for IPv6 address and swigall to boot --- src/include/switch_utils.h | 10 +- .../languages/mod_managed/freeswitch_wrap.cxx | 135 +++++++++++++++- src/mod/languages/mod_managed/managed/swig.cs | 144 +++++++++++++++++- src/mod/languages/mod_perl/mod_perl_wrap.cpp | 6 +- src/switch_core.c | 31 +++- src/switch_utils.c | 124 ++++++++++++--- 6 files changed, 407 insertions(+), 43 deletions(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 3a4f8b253b..e2a7335226 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -54,6 +54,13 @@ SWITCH_DECLARE(int) switch_isspace(int c); SWITCH_DECLARE(int) switch_isupper(int c); SWITCH_DECLARE(int) switch_isxdigit(int c); +typedef union{ + uint32_t v4; + struct in6_addr v6; +} ip_t; + +SWITCH_DECLARE(switch_bool_t) switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _mask); + #define switch_goto_status(_status, _label) status = _status; goto _label #define switch_goto_int(_n, _i, _label) _n = _i; goto _label #define switch_samples_per_packet(rate, interval) ((uint32_t)((float)rate / (1000.0f / (float)interval))) @@ -694,7 +701,7 @@ SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char clos -SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp); +SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp); 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); @@ -703,6 +710,7 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_networ 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_token(switch_network_list_t *list, uint32_t ip, const char **token); +SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token); #define switch_network_list_validate_ip(_list, _ip) switch_network_list_validate_ip_token(_list, _ip, NULL); #define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net ? _net == _ip : 1) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 13136d99e8..ca001f64b1 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -11949,6 +11949,111 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_isxdigit(int jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_ip_t_v4_set(void * jarg1, unsigned long jarg2) { + ip_t *arg1 = (ip_t *) 0 ; + uint32_t arg2 ; + + arg1 = (ip_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->v4 = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_ip_t_v4_get(void * jarg1) { + unsigned long jresult ; + ip_t *arg1 = (ip_t *) 0 ; + uint32_t result; + + arg1 = (ip_t *)jarg1; + result = (uint32_t) ((arg1)->v4); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_ip_t_v6_set(void * jarg1, void * jarg2) { + ip_t *arg1 = (ip_t *) 0 ; + in6_addr arg2 ; + in6_addr *argp2 ; + + arg1 = (ip_t *)jarg1; + argp2 = (in6_addr *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null in6_addr", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->v6 = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_ip_t_v6_get(void * jarg1) { + void * jresult ; + ip_t *arg1 = (ip_t *) 0 ; + in6_addr result; + + arg1 = (ip_t *)jarg1; + result = ((arg1)->v6); + jresult = new in6_addr((in6_addr &)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_ip_t() { + void * jresult ; + ip_t *result = 0 ; + + result = (ip_t *)new ip_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_ip_t(void * jarg1) { + ip_t *arg1 = (ip_t *) 0 ; + + arg1 = (ip_t *)jarg1; + delete arg1; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_testv6_subnet(void * jarg1, void * jarg2, void * jarg3) { + int jresult ; + ip_t arg1 ; + ip_t arg2 ; + ip_t arg3 ; + switch_bool_t result; + ip_t *argp1 ; + ip_t *argp2 ; + ip_t *argp3 ; + + argp1 = (ip_t *)jarg1; + if (!argp1) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null ip_t", 0); + return 0; + } + arg1 = *argp1; + argp2 = (ip_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null ip_t", 0); + return 0; + } + arg2 = *argp2; + argp3 = (ip_t *)jarg3; + if (!argp3) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null ip_t", 0); + return 0; + } + arg3 = *argp3; + result = (switch_bool_t)switch_testv6_subnet(arg1,arg2,arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_SMAX_get() { int jresult ; int result; @@ -12906,14 +13011,14 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_file_path(char * jarg1) { SWIGEXPORT int SWIGSTDCALL CSharp_switch_parse_cidr(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { int jresult ; char *arg1 = (char *) 0 ; - uint32_t *arg2 = (uint32_t *) 0 ; - uint32_t *arg3 = (uint32_t *) 0 ; + ip_t *arg2 = (ip_t *) 0 ; + ip_t *arg3 = (ip_t *) 0 ; uint32_t *arg4 = (uint32_t *) 0 ; int result; arg1 = (char *)jarg1; - arg2 = (uint32_t *)jarg2; - arg3 = (uint32_t *)jarg3; + arg2 = (ip_t *)jarg2; + arg3 = (ip_t *)jarg3; arg4 = (uint32_t *)jarg4; result = (int)switch_parse_cidr((char const *)arg1,arg2,arg3,arg4); jresult = result; @@ -12991,6 +13096,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_network_list_validate_ip_token(void * j } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_network_list_validate_ip6_token(void * jarg1, void * jarg2, void * jarg3) { + int jresult ; + switch_network_list_t *arg1 = (switch_network_list_t *) 0 ; + ip_t arg2 ; + char **arg3 = (char **) 0 ; + switch_bool_t result; + ip_t *argp2 ; + + arg1 = (switch_network_list_t *)jarg1; + argp2 = (ip_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null ip_t", 0); + return 0; + } + arg2 = *argp2; + arg3 = (char **)jarg3; + result = (switch_bool_t)switch_network_list_validate_ip6_token(arg1,arg2,(char const **)arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_dow_int2str(int jarg1) { char * jresult ; int arg1 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index e31d444669..bd901911ed 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -2643,6 +2643,12 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _mask) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_testv6_subnet(ip_t.getCPtr(_ip), ip_t.getCPtr(_net), ip_t.getCPtr(_mask)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + public static int _zstr(string s) { int ret = freeswitchPINVOKE._zstr(s); return ret; @@ -2949,8 +2955,8 @@ public class freeswitch { return ret; } - public static int switch_parse_cidr(string arg0, SWIGTYPE_p_unsigned_long ip, SWIGTYPE_p_unsigned_long mask, SWIGTYPE_p_unsigned_long bitp) { - int ret = freeswitchPINVOKE.switch_parse_cidr(arg0, SWIGTYPE_p_unsigned_long.getCPtr(ip), SWIGTYPE_p_unsigned_long.getCPtr(mask), SWIGTYPE_p_unsigned_long.getCPtr(bitp)); + public static int switch_parse_cidr(string arg0, ip_t ip, ip_t mask, SWIGTYPE_p_unsigned_long bitp) { + int ret = freeswitchPINVOKE.switch_parse_cidr(arg0, ip_t.getCPtr(ip), ip_t.getCPtr(mask), SWIGTYPE_p_unsigned_long.getCPtr(bitp)); return ret; } @@ -2974,6 +2980,12 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_network_list_validate_ip6_token(SWIGTYPE_p_switch_network_list list, ip_t ip, ref string token) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_network_list_validate_ip6_token(SWIGTYPE_p_switch_network_list.getCPtr(list), ip_t.getCPtr(ip), ref token); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + public static string switch_dow_int2str(int val) { string ret = freeswitchPINVOKE.switch_dow_int2str(val); return ret; @@ -8430,6 +8442,27 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_isxdigit")] public static extern int switch_isxdigit(int jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_ip_t_v4_set")] + public static extern void ip_t_v4_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_ip_t_v4_get")] + public static extern uint ip_t_v4_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_ip_t_v6_set")] + public static extern void ip_t_v6_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_ip_t_v6_get")] + public static extern IntPtr ip_t_v6_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_ip_t")] + public static extern IntPtr new_ip_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_ip_t")] + public static extern void delete_ip_t(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_testv6_subnet")] + public static extern int switch_testv6_subnet(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_SMAX_get")] public static extern int SWITCH_SMAX_get(); @@ -8628,6 +8661,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_network_list_validate_ip_token")] public static extern int switch_network_list_validate_ip_token(HandleRef jarg1, uint jarg2, ref string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_network_list_validate_ip6_token")] + public static extern int switch_network_list_validate_ip6_token(HandleRef jarg1, HandleRef jarg2, ref string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_int2str")] public static extern string switch_dow_int2str(int jarg1); @@ -13785,6 +13821,75 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class ip_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal ip_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(ip_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~ip_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_ip_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public uint v4 { + set { + freeswitchPINVOKE.ip_t_v4_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.ip_t_v4_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_in6_addr v6 { + set { + freeswitchPINVOKE.ip_t_v6_set(swigCPtr, SWIGTYPE_p_in6_addr.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_in6_addr ret = new SWIGTYPE_p_in6_addr(freeswitchPINVOKE.ip_t_v6_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public ip_t() : this(freeswitchPINVOKE.new_ip_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class IvrMenu : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -16398,6 +16503,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_in6_addr { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_in6_addr(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_in6_addr() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_in6_addr obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_int { private HandleRef swigCPtr; @@ -28053,7 +28188,10 @@ public enum switch_rtp_bug_flag_t { RTP_BUG_NONE = 0, RTP_BUG_CISCO_SKIP_MARK_BIT_2833 = (1 << 0), RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 = (1 << 1), - RTP_BUG_IGNORE_MARK_BIT = (1 << 2) + RTP_BUG_IGNORE_MARK_BIT = (1 << 2), + RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3), + RTP_BUG_START_SEQ_AT_ZERO = (1 << 4), + RTP_BUG_NEVER_SEND_MARKER = (1 << 5) } } diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index 2efbdf1abc..370c88bc99 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -9732,17 +9732,17 @@ XS(SWIG_init) { SWIG_TypeClientData(SWIGTYPE_p_IVRMenu, (void*) "freeswitch::IVRMenu"); SWIG_TypeClientData(SWIGTYPE_p_API, (void*) "freeswitch::API"); SWIG_TypeClientData(SWIGTYPE_p_input_callback_state, (void*) "freeswitch::input_callback_state_t"); - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_HUP", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_HUP))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_FREE", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_FREE))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_RDLOCK", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_RDLOCK))); SvREADONLY_on(sv); diff --git a/src/switch_core.c b/src/switch_core.c index bd4b00d2ed..0c1263ac95 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -901,16 +901,25 @@ static switch_ip_list_t IP_LIST = { 0 }; SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token) { switch_network_list_t *list; - uint32_t ip, net, mask, bits; + ip_t ip, mask, net; + uint32_t bits; + char *ipv6 = strchr(ip_str,':'); switch_bool_t ok = SWITCH_FALSE; switch_mutex_lock(runtime.global_mutex); - switch_inet_pton(AF_INET, ip_str, &ip); - - ip = htonl(ip); + if (ipv6) { + switch_inet_pton(AF_INET6, ip_str, &ip); + } else { + switch_inet_pton(AF_INET, ip_str, &ip); + ip.v4 = htonl(ip.v4); + } if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) { - ok = switch_network_list_validate_ip_token(list, ip, token); + if (ipv6) { + ok = switch_network_list_validate_ip6_token(list, ip, token); + } else { + ok = switch_network_list_validate_ip_token(list, ip.v4, token); + } } else if (strchr(list_name, '/')) { if (strchr(list_name, ',')) { char *list_name_dup = strdup(list_name); @@ -923,15 +932,21 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_ int i; for (i = 0; i < argc; i++) { switch_parse_cidr(argv[i], &net, &mask, &bits); - if ((ok = switch_test_subnet(ip, net, mask))) { - break; + if (ipv6) { + if ((ok = switch_testv6_subnet(ip, net, mask))){ + break; + } + } else { + if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) { + break; + } } } } free(list_name_dup); } else { switch_parse_cidr(list_name, &net, &mask, &bits); - ok = switch_test_subnet(ip, net, mask); + ok = switch_test_subnet(ip.v4, net.v4, mask.v4); } } switch_mutex_unlock(runtime.global_mutex); diff --git a/src/switch_utils.c b/src/switch_utils.c index 2872f10a6e..75be02a31f 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -39,9 +39,10 @@ #define ESCAPE_META '\\' struct switch_network_node { - uint32_t ip; - uint32_t mask; + ip_t ip; + ip_t mask; uint32_t bits; + int family; switch_bool_t ok; char *token; char *str; @@ -140,6 +141,50 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t return SWITCH_STATUS_SUCCESS; } +#define IN6_AND_MASK(result, ip, mask) \ + ((uint32_t *) (result))[0] =((const uint32_t *) (ip))[0] & ((const uint32_t *)(mask))[0]; \ + ((uint32_t *) (result))[1] =((const uint32_t *) (ip))[1] & ((const uint32_t *)(mask))[1]; \ + ((uint32_t *) (result))[2] =((const uint32_t *) (ip))[2] & ((const uint32_t *)(mask))[2]; \ + ((uint32_t *) (result))[3] =((const uint32_t *) (ip))[3] & ((const uint32_t *)(mask))[3]; +SWITCH_DECLARE(switch_bool_t) switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _mask) { + if (!IN6_IS_ADDR_UNSPECIFIED(&_mask.v6)) { + struct in6_addr a, b; + IN6_AND_MASK(&a, &_net, &_mask); + IN6_AND_MASK(&b, &_ip, &_mask); + return !memcmp(&a,&b, sizeof(struct in6_addr)); + } else { + if (!IN6_IS_ADDR_UNSPECIFIED(&_net.v6)) { + return !memcmp(&_net,&_ip,sizeof(struct in6_addr)); + } + else return SWITCH_TRUE; + } +} +SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token) +{ + 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->family == AF_INET) continue; + if (node->bits > bits && switch_testv6_subnet(ip, node->ip, node->mask)) { + if (node->ok) { + ok = SWITCH_TRUE; + } else { + ok = SWITCH_FALSE; + } + + bits = node->bits; + + if (token) { + *token = node->token; + } + } + } + + return ok; +} + SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token) { switch_network_node_t *node; @@ -147,7 +192,8 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_netwo 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->family == AF_INET6) continue; /* want AF_INET */ + if (node->bits > bits && switch_test_subnet(ip, node->ip.v4, node->mask.v4)) { if (node->ok) { ok = SWITCH_TRUE; } else { @@ -168,7 +214,8 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_netwo SWITCH_DECLARE(switch_status_t) switch_network_list_perform_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token) { - uint32_t ip, mask, bits; + ip_t ip, mask; + uint32_t bits; switch_network_node_t *node; if (switch_parse_cidr(cidr_str, &ip, &mask, &bits)) { @@ -185,6 +232,12 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_perform_add_cidr_token(switc node->bits = bits; node->str = switch_core_strdup(list->pool, cidr_str); + if (strchr(cidr_str,':')) { + node->family = AF_INET6; + } else { + node->family = AF_INET; + } + if (!zstr(token)) { node->token = switch_core_strdup(list->pool, token); } @@ -227,7 +280,7 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_networ 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; + ip_t ip, mask; switch_network_node_t *node; switch_inet_pton(AF_INET, host, &ip); @@ -235,14 +288,15 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network node = switch_core_alloc(list->pool, sizeof(*node)); - node->ip = ntohl(ip); - node->mask = ntohl(mask); + node->ip.v4 = ntohl(ip.v4); + node->mask.v4 = ntohl(mask.v4); 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; + mask.v4 = mask.v4 - ((mask.v4 >> 1) & 0x55555555); + mask.v4 = (mask.v4 & 0x33333333) + ((mask.v4 >> 2) & 0x33333333); + node->bits = (((mask.v4 + (mask.v4 >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; + node->str = switch_core_sprintf(list->pool, "%s:%s", host, mask_str); node->next = list->node_head; @@ -252,13 +306,16 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network } -SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp) +SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp) { char host[128]; char *bit_str; int32_t bits; + const char *ipv6; + ip_t *maskv = mask; + ip_t *ipv = ip; - switch_copy_string(host, string, sizeof(host)); + memcpy(host, string, sizeof(host)); bit_str = strchr(host, '/'); if (!bit_str) { @@ -267,17 +324,36 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *bit_str++ = '\0'; bits = atoi(bit_str); + ipv6 = strchr(string, ':'); + if (ipv6) { + int i,n; + if (bits < 0 || bits > 128) { + return -2; + } + bits = atoi(bit_str); + switch_inet_pton(AF_INET6, host, (unsigned char *)ip); + for (n=bits,i=0 ;i < 16; i++){ + if (n >= 8) { + maskv->v6.s6_addr[i] = 0xFF; + n -= 8; + } else if (n < 8) { + maskv->v6.s6_addr[i] = 0xFF & ~(0xFF >> n); + n -= n; + } else if (n == 0) { + maskv->v6.s6_addr[i] = 0x00; + } + } + } else { + if (bits < 0 || bits > 32) { + return -2; + } - if (bits < 0 || bits > 32) { - return -2; + bits = atoi(bit_str); + switch_inet_pton(AF_INET, host, (unsigned char *)ip); + ipv->v4 = htonl(ipv->v4); + + maskv->v4 = 0xFFFFFFFF & ~(0xFFFFFFFF >> bits); } - - bits = atoi(bit_str); - switch_inet_pton(AF_INET, host, ip); - *ip = htonl(*ip); - - *mask = 0xFFFFFFFF & ~(0xFFFFFFFF >> bits); - *bitp = bits; return 0; @@ -394,7 +470,7 @@ SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size if (++y != 72) { continue; } - //out[bytes++] = '\n'; + /* out[bytes++] = '\n'; */ y = 0; } } @@ -963,7 +1039,7 @@ static int get_netmask(struct sockaddr_in *me, int *mask) if (ip.s_addr == me->sin_addr.s_addr) { ioctl(sock, SIOCGIFNETMASK, &ifreqs[i]); sin = (struct sockaddr_in *) &ifreqs[i].ifr_addr; - //mask = sin->sin_addr; + /* mask = sin->sin_addr; */ *mask = sin->sin_addr.s_addr; r = 0; break; @@ -1094,7 +1170,7 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma break; case AF_INET6: switch_copy_string(buf, "::1", len); - base = "2001:503:BA3E::2:30"; // DNS Root server A + base = "2001:503:BA3E::2:30"; /* DNS Root server A */ break; default: base = "127.0.0.1";