[asterisk-commits] simon.perreault: branch group/v6 r84406 - in /team/group/v6/trunk: channels/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 2 13:42:47 CDT 2007


Author: simon.perreault
Date: Tue Oct  2 13:42:44 2007
New Revision: 84406

URL: http://svn.digium.com/view/asterisk?view=rev&rev=84406
Log:
IPv6-enabled ACLs! Woot!

Modified:
    team/group/v6/trunk/channels/chan_iax2.c
    team/group/v6/trunk/channels/chan_mgcp.c
    team/group/v6/trunk/channels/chan_sip.c
    team/group/v6/trunk/channels/chan_skinny.c
    team/group/v6/trunk/configs/iax.conf.sample
    team/group/v6/trunk/configs/sip.conf.sample
    team/group/v6/trunk/include/asterisk/acl.h
    team/group/v6/trunk/main/acl.c
    team/group/v6/trunk/main/manager.c

Modified: team/group/v6/trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/channels/chan_iax2.c?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/channels/chan_iax2.c (original)
+++ team/group/v6/trunk/channels/chan_iax2.c Tue Oct  2 13:42:44 2007
@@ -3006,6 +3006,7 @@
 {
 	struct iax2_peer *peer;
 	int res = -1;
+	socklen_t dummy;
 
 	ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
 	cai->sockfd = defaultsockfd;
@@ -3014,7 +3015,8 @@
 
 	if (!(peer = find_peer(peername, 1))) {
 		cai->found = 0;
-		if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
+		if (ast_get_ip_or_srv((struct sockaddr*)sin, &dummy, peername,
+					srvlookup ? "_iax._udp" : NULL)) {
 			ast_log(LOG_WARNING, "No such host: %s\n", peername);
 			return -1;
 		}
@@ -5165,7 +5167,8 @@
 	while ((user = ao2_iterator_next(&i))) {
 		if ((ast_strlen_zero(iaxs[callno]->username) ||				/* No username specified */
 			!strcmp(iaxs[callno]->username, user->name))	/* Or this username specified */
-			&& ast_apply_ha(user->ha, sin) 	/* Access is permitted from this IP */
+			&& ast_apply_ha(user->ha, (struct sockaddr*) sin, sizeof(*sin))
+				/* Access is permitted from this IP */
 			&& (ast_strlen_zero(iaxs[callno]->context) ||			/* No context specified */
 			     apply_context(user->contexts, iaxs[callno]->context))) {			/* Context is permitted */
 			if (!ast_strlen_zero(iaxs[callno]->username)) {
@@ -5524,7 +5527,7 @@
 		goto return_unref;
 	}
 
-	if (!ast_apply_ha(p->ha, sin)) {
+	if (!ast_apply_ha(p->ha, (struct sockaddr*) sin, sizeof(*sin))) {
 		if (authdebug)
 			ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
 		goto return_unref;
@@ -9315,6 +9318,7 @@
 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
 {
 	struct sockaddr_in sin;
+	socklen_t dummy;
 	int nonlocal = 1;
 	int port = IAX_DEFAULT_PORTNO;
 	int sockfd = defaultsockfd;
@@ -9334,7 +9338,7 @@
 			port = IAX_DEFAULT_PORTNO;
 	}
 	
-	if (!ast_get_ip(&sin, addr)) {
+	if (!ast_get_ip((struct sockaddr*) &sin, &dummy, addr)) {
 		struct ast_netsock *sock;
 		int res;
 
@@ -9531,7 +9535,9 @@
 				if (!maskfound)
 					inet_aton("255.255.255.255", &peer->mask);
 			} else if (!strcasecmp(v->name, "defaultip")) {
-				if (ast_get_ip(&peer->defaddr, v->value))
+				socklen_t dummy;
+				if (ast_get_ip((struct sockaddr*) &peer->defaddr, &dummy,
+							v->value))
 					return peer_unref(peer);
 			} else if (!strcasecmp(v->name, "sourceaddress")) {
 				peer_set_srcaddr(peer, v->value);

Modified: team/group/v6/trunk/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/channels/chan_mgcp.c?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/channels/chan_mgcp.c (original)
+++ team/group/v6/trunk/channels/chan_mgcp.c Tue Oct  2 13:42:44 2007
@@ -3576,7 +3576,9 @@
 						ast_sched_del(sched, gw->expire);
 					gw->expire = -1;
 					gw->dynamic = 0;
-					if (ast_get_ip(&gw->addr, v->value)) {
+					socklen_t dummy;
+					if (ast_get_ip((struct sockaddr*) &gw->addr,
+								&dummy, v->value)) {
 						if (!gw_reload) {
 							ast_mutex_destroy(&gw->msgs_lock);
 							ast_free(gw);
@@ -3585,7 +3587,9 @@
 					}
 				}
 			} else if (!strcasecmp(v->name, "defaultip")) {
-				if (ast_get_ip(&gw->defaddr, v->value)) {
+				socklen_t dummy;
+				if (ast_get_ip((struct sockaddr*) &gw->defaddr, &dummy,
+							v->value)) {
 					if (!gw_reload) {
 						ast_mutex_destroy(&gw->msgs_lock);
 						ast_free(gw);

Modified: team/group/v6/trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/channels/chan_sip.c?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/channels/chan_sip.c (original)
+++ team/group/v6/trunk/channels/chan_sip.c Tue Oct  2 13:42:44 2007
@@ -1978,7 +1978,7 @@
 	int port;
 
 	/* XXX Todo - if we have proxy port, don't do SRV */
-	if (ast_viget_ip_or_srv((struct sockaddr*)&proxy->ip, &proxy->ip_len,
+	if (ast_get_ip_or_srv((struct sockaddr*)&proxy->ip, &proxy->ip_len,
 				proxy->name, global_srvlookup ? "_sip._udp" : NULL) < 0) {
 		ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
 		return FALSE;
@@ -2224,9 +2224,9 @@
 
 	if (localaddr && externip_len &&
 			(!ast_vinetsock_sa_is_ipv4(them) ||
-			 ast_apply_ha(localaddr, (struct sockaddr_in*)them)) &&
+			 ast_apply_ha(localaddr, them, them_len)) &&
 			(!ast_vinetsock_sa_is_ipv4(us) || !global_matchexterniplocally ||
-			 !ast_apply_ha(localaddr, (struct sockaddr_in*)us))) {
+			 !ast_apply_ha(localaddr, us, *us_len))) {
 		if (externexpire && time(NULL) >= externexpire) {
 			externexpire = time(NULL) + externrefresh;
 			if (ast_vinetsock_sa_fromstr(externhost, sbuf, (struct sockaddr*)&externip, &externip_len, AF_INET, 0))
@@ -9513,7 +9513,7 @@
 	build_contact(p);
 	peer = find_peer(name, NULL, 0, 1);
 	if (!(peer && (!ast_vinetsock_sa_is_ipv4(sa) ||
-		ast_apply_ha(peer->ha, (struct sockaddr_in*)sa)))) {
+		ast_apply_ha(peer->ha, sa, sa_len)))) {
 		/* Peer fails ACL check */
 		if (peer) {
 			unref_peer(peer);
@@ -10327,7 +10327,7 @@
 			ast_verbose("No user '%s' in SIP users list\n", of);
 		return AUTH_DONT_KNOW;
 	}
-	if (ast_vinetsock_sa_is_ipv4(sa) && !ast_apply_ha(user->ha, (struct sockaddr_in*)sa)) {
+	if (ast_vinetsock_sa_is_ipv4(sa) && !ast_apply_ha(user->ha, sa, sa_len)) {
 		if (debug)
 			ast_verbose("Found user '%s' for '%s', but fails host access\n",
 				user->name, of);
@@ -11987,12 +11987,14 @@
 	{
 		struct ast_ha *d;
 		const char *prefix = "Localnet:";
-		char buf[INET_ADDRSTRLEN]; /* need to print two addresses */
+		char addrbuf[NI_MAXHOST], maskbuf[NI_MAXHOST];
 
 		for (d = localaddr; d ; prefix = "", d = d->next) {
-			ast_cli(a->fd, "  %-24s%s/%s\n",
-			    prefix, ast_inet_ntoa(d->netaddr),
-			    inet_ntop(AF_INET, &d->netmask, buf, sizeof(buf)) );
+			ast_vinetsock_sa_get_host((struct sockaddr*)&d->netaddr,
+					d->netlen, addrbuf, sizeof(addrbuf));
+			ast_vinetsock_sa_get_host((struct sockaddr*)&d->netmask,
+					d->netlen, maskbuf, sizeof(addrbuf));
+			ast_cli(a->fd, "  %-24s%s/%s\n", prefix, addrbuf, maskbuf);
 		}
 	}
 	ast_vinetsock_sa_get_hostport( (struct sockaddr*) &stunaddr,
@@ -17899,7 +17901,7 @@
 				peer->host_dynamic = FALSE;
 				ast_vinetsock_str2hp(hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
 						v->value, 0, (void *)&end);
-				if (ast_viget_ip_or_srv((struct sockaddr*)&peer->addr,
+				if (ast_get_ip_or_srv((struct sockaddr*)&peer->addr,
 							&peer->addr_len,
 							hbuf, global_srvlookup ? "_sip._udp" : NULL)) {
 					unref_peer(peer);

Modified: team/group/v6/trunk/channels/chan_skinny.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/channels/chan_skinny.c?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/channels/chan_skinny.c (original)
+++ team/group/v6/trunk/channels/chan_skinny.c Tue Oct  2 13:42:44 2007
@@ -1667,7 +1667,8 @@
 	ast_mutex_lock(&devicelock);
 	for (d = devices; d; d = d->next) {
 		if (!strcasecmp(req->data.reg.name, d->id)
-				&& ast_apply_ha(d->ha, &(s->sin))) {
+				&& ast_apply_ha(d->ha, (struct sockaddr*) &s->sin,
+					sizeof(s->sin))) {
 			s->device = d;
 			d->type = letohl(req->data.reg.type);
 			if (ast_strlen_zero(d->version_id)) {
@@ -2740,7 +2741,8 @@
 			ast_copy_string(device_vmexten, vmexten, sizeof(device_vmexten));
 		while(v) {
 			if (!strcasecmp(v->name, "host")) {
-				if (ast_get_ip(&d->addr, v->value)) {
+				socklen_t dummy;
+				if (ast_get_ip((struct sockaddr*) &d->addr, &dummy, v->value)) {
 					ast_free(d);
 					return NULL;
 				}

Modified: team/group/v6/trunk/configs/iax.conf.sample
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/configs/iax.conf.sample?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/configs/iax.conf.sample (original)
+++ team/group/v6/trunk/configs/iax.conf.sample Tue Oct  2 13:42:44 2007
@@ -365,8 +365,10 @@
 ;                       ; if this limit is reached until they expire or a reply is received.
 ;callerid="Mark Spencer" <(256) 428-6275>
 ;deny=0.0.0.0/0.0.0.0
+;deny=::/::
 ;accountcode=markster0101
 ;permit=209.16.236.73/255.255.255.0
+;permit=::ffff:209.16.236.73/::ffff255.255.255.0
 ;language=en		; Use english as default language
 ;
 ; Peers may also be specified, with a secret and

Modified: team/group/v6/trunk/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/configs/sip.conf.sample?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/configs/sip.conf.sample (original)
+++ team/group/v6/trunk/configs/sip.conf.sample Tue Oct  2 13:42:44 2007
@@ -775,7 +775,9 @@
 ;pickupgroup=1,3-5		; We can do call pick-p for call group 1,3,4,5
 ;defaultip=192.168.0.60		; IP address to use if peer has not registered
 ;deny=0.0.0.0/0.0.0.0		; ACL: Control access to this account based on IP address
+;deny=::/::
 ;permit=192.168.0.60/255.255.255.0
+;permit=::ffff:192.168.0.60/255.255.255.0
 
 ;[cisco1]
 ;type=friend

Modified: team/group/v6/trunk/include/asterisk/acl.h
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/include/asterisk/acl.h?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/include/asterisk/acl.h (original)
+++ team/group/v6/trunk/include/asterisk/acl.h Tue Oct  2 13:42:44 2007
@@ -48,18 +48,11 @@
  */
 struct ast_ha {
         /* Host access rule */
-        struct in_addr netaddr;  
-        struct in_addr netmask;
+        struct sockaddr_storage netaddr;  
+        struct sockaddr_storage netmask;
+	socklen_t netlen;  /* netaddr and netmask share the same length */
         int sense;
         struct ast_ha *next;
-};
-
-struct ast_viha {
-	struct sockaddr_storage netaddr;
-	struct sockaddr_storage netmask;
-	int prefixlen;
-	int sense;
-	struct ast_viha *next;
 };
 
 /*! \brief Free host access list */
@@ -69,14 +62,15 @@
 struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path, int *error);
 
 /*! \brief Check IP address with host access list */
-int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin);
+int ast_apply_ha(struct ast_ha *ha, struct sockaddr *sa, socklen_t salen);
 
 /*! \brief Copy host access list */
 struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);
 
-int ast_get_ip(struct sockaddr_in *sin, const char *value);
+int ast_get_ip(struct sockaddr *sa, socklen_t *sa_len, const char *value);
 
-int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service);
+int ast_get_ip_or_srv(struct sockaddr *sa, socklen_t *sa_len, const char *value,
+		const char *service);
 
 int ast_ouraddrfor(struct in_addr *them, struct in_addr *us);
 
@@ -87,19 +81,6 @@
 int ast_str2tos(const char *value, unsigned int *tos);
 const char *ast_tos2str(unsigned int tos);
 
-/* IP version independent (IPv4 and IPv6) version of ACL
- * using a new namespace to avoid conflict with current code
- * so any channel and module can transition to IPv6 one at a time.
- * duplicate code however is not automatically synched with changes above
- *
- * \author Marc Blanchet <marc.blanchet at viagenie.ca>
- * Copyright (C) 2007, Viagenie, Inc.
- */
-struct ast_viha;
-
-int ast_viget_ip(struct sockaddr *sa, socklen_t *sa_len, const char *value);
-int ast_viget_ip_or_srv(struct sockaddr *sa, socklen_t *sa_len, const char *value, const char *service);
-
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/group/v6/trunk/main/acl.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/main/acl.c?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/main/acl.c (original)
+++ team/group/v6/trunk/main/acl.c Tue Oct  2 13:42:44 2007
@@ -69,6 +69,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/lock.h"
 #include "asterisk/srv.h"
+#include "asterisk/netsock.h"
 
 struct my_ifreq {
 	char ifrn_name[IFNAMSIZ];	/* Interface name, e.g. "eth0", "ppp0", etc.  */
@@ -132,111 +133,195 @@
 struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path, int *error)
 {
 	struct ast_ha *ha;
-	char *nm = "255.255.255.255";
+	char *nm;
 	char tmp[256];
 	struct ast_ha *prev = NULL;
 	struct ast_ha *ret;
-	int x, z;
-	unsigned int y;
+	int x, i;
+	socklen_t masklen;
 
 	ret = path;
 	while (path) {
 		prev = path;
 		path = path->next;
 	}
-	if ((ha = ast_malloc(sizeof(*ha)))) {
-		ast_copy_string(tmp, stuff, sizeof(tmp));
-		nm = strchr(tmp, '/');
-		if (!nm) {
-			nm = "255.255.255.255";
-		} else {
-			*nm = '\0';
-			nm++;
-		}
-		if (!strchr(nm, '.')) {
-			if ((sscanf(nm, "%d", &x) == 1) && (x >= 0) && (x <= 32)) {
-				y = 0;
-				for (z = 0; z < x; z++) {
-					y >>= 1;
-					y |= 0x80000000;
-				}
-				ha->netmask.s_addr = htonl(y);
+
+	if (!(ha = ast_malloc(sizeof(*ha))))
+		return ret;
+
+	ast_copy_string(tmp, stuff, sizeof(tmp));
+	nm = strchr(tmp, '/');
+	if (nm) {
+		*nm = '\0';
+		nm++;
+	}
+
+	if (ast_vinetsock_sa_fromstr(tmp, NULL, (struct sockaddr*) &ha->netaddr,
+				&ha->netlen, AF_UNSPEC, 0)) {
+		ast_log(LOG_WARNING, "%s is not a valid address\n", tmp);
+		if (error)
+			*error = 1;
+		ast_free(ha);
+		return ret;
+	}
+
+	/* Gotos are bad, mkay? */
+	if (!strchr(nm, '.') && !strchr(nm, ':')) {
+		if ((sscanf(nm, "%d", &x) == 1) && x >= 0) {
+			memcpy(&ha->netmask, &ha->netaddr, ha->netlen);
+			switch (((struct sockaddr*) &ha->netmask)->sa_family) {
+			case AF_INET:
+				if (x > 32) goto nm_error;
+				for (i = 0; i < 4; ++i)
+					((unsigned char*) &((struct sockaddr_in*)
+						&ha->netmask)->sin_addr.s_addr)[i] =
+						~((1 << (x - (32-(i+1)*8))) - 1);
+				break;
+			case AF_INET6:
+				if (x > 128) goto nm_error;
+				for (i = 0; i < 16; ++i)
+					((struct sockaddr_in6*) &ha->netmask)
+						->sin6_addr.s6_addr[i] =
+						~((1 << (x - (128-(i+1)*8))) - 1);
+				break;
 			}
-		} else if (!inet_aton(nm, &ha->netmask)) {
-			ast_log(LOG_WARNING, "%s is not a valid netmask\n", nm);
-			if (error)
-				*error = 1;
-			ast_free(ha);
-			return ret;
-		}
-		if (!inet_aton(tmp, &ha->netaddr)) {
-			ast_log(LOG_WARNING, "%s is not a valid IP\n", tmp);
-			if (error)
-				*error = 1;
-			ast_free(ha);
-			return ret;
-		}
-		ha->netaddr.s_addr &= ha->netmask.s_addr;
-		if (!strncasecmp(sense, "p", 1)) {
-			ha->sense = AST_SENSE_ALLOW;
-		} else {
-			ha->sense = AST_SENSE_DENY;
-		}
-		ha->next = NULL;
-		if (prev) {
-			prev->next = ha;
-		} else {
-			ret = ha;
-		}
-	}
-	ast_debug(1, "%s/%s appended to acl for peer\n", stuff, nm);
+		}
+	}
+	else if (ast_vinetsock_sa_fromstr(nm, NULL, (struct sockaddr*) &ha->netmask,
+				&masklen, AF_UNSPEC, 0) || masklen != ha->netlen)
+		goto nm_error;
+
+	switch (((struct sockaddr*) &ha->netmask)->sa_family) {
+	case AF_INET:
+		((struct sockaddr_in*) &ha->netaddr)->sin_addr.s_addr &=
+			((struct sockaddr_in*) &ha->netmask)->sin_addr.s_addr;
+		break;
+	case AF_INET6:
+		for (i = 0; i < 16; ++i)
+			((struct sockaddr_in6*) &ha->netaddr)->sin6_addr.s6_addr[i] &=
+				((struct sockaddr_in6*)
+				 &ha->netmask)->sin6_addr.s6_addr[i];
+	}
+
+	if (!strncasecmp(sense, "p", 1)) {
+		ha->sense = AST_SENSE_ALLOW;
+	} else {
+		ha->sense = AST_SENSE_DENY;
+	}
+	ha->next = NULL;
+	if (prev) {
+		prev->next = ha;
+	} else {
+		ret = ha;
+	}
+
+	ast_debug(1, "%s/%s appended to acl for peer\n", tmp, nm);
 	return ret;
-}
-
-int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
+
+nm_error:
+	ast_log(LOG_WARNING, "%s is not a valid netmask\n", nm);
+	if (error)
+		*error = 1;
+	ast_free(ha);
+	return ret;
+}
+
+static int test_mask_ipv4(struct sockaddr_in *sa, struct sockaddr_in *netmask,
+		struct sockaddr_in *netaddr)
+{
+	if ((sa->sin_addr.s_addr & netmask->sin_addr.s_addr) != netaddr->sin_addr.s_addr)
+		return 0;
+	return 1;
+}
+
+static int test_mask_ipv6(struct sockaddr_in6 *sa, struct sockaddr_in6 *netmask,
+		struct sockaddr_in6 *netaddr)
+{
+	int i;
+
+	for (i = 0; i < 16; ++i)
+		if ((sa->sin6_addr.s6_addr[i] & netmask->sin6_addr.s6_addr[i])
+				!= netaddr->sin6_addr.s6_addr[i])
+			return 0;
+
+	return 1;
+}
+
+static int test_scope_ipv6(struct sockaddr_in6 *sa, struct sockaddr_in6 *netmask,
+		struct sockaddr_in6 *netaddr)
+{
+	if (sa->sin6_scope_id != netmask->sin6_scope_id ||
+			sa->sin6_scope_id != netaddr->sin6_scope_id)
+		return 0;
+	return 1;
+}
+
+int ast_apply_ha(struct ast_ha *ha, struct sockaddr *sa, socklen_t salen)
 {
 	/* Start optimistic */
 	int res = AST_SENSE_ALLOW;
-	while (ha) {
-#if 0	/* debugging code */
-		char iabuf[INET_ADDRSTRLEN];
-		char iabuf2[INET_ADDRSTRLEN];
-		/* DEBUG */
-		ast_copy_string(iabuf, ast_inet_ntoa(sin->sin_addr), sizeof(iabuf));
-		ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
-		ast_debug(1, "##### Testing %s with %s\n", iabuf, iabuf2);
-#endif
-		/* For each rule, if this address and the netmask = the net address
-		   apply the current rule */
-		if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == ha->netaddr.s_addr)
-			res = ha->sense;
-		ha = ha->next;
+
+	/* For each rule, if this address and the netmask = the net address
+	   apply the current rule.
+	   With IPv6, we also need to check the scope ID. */
+	for ( ; ha; ha = ha->next ) {
+
+		/* ACLs only apply to same-family addresses. */
+		if (salen != ha->netlen
+				|| sa->sa_family !=
+				((struct sockaddr*) &ha->netaddr)->sa_family
+				|| sa->sa_family !=
+				((struct sockaddr*) &ha->netmask)->sa_family)
+			continue;
+
+		/* ACLs are really a protocol-dependent thing. */
+		switch (sa->sa_family) {
+		case AF_INET:
+			if (!test_mask_ipv4((struct sockaddr_in*) sa,
+						(struct sockaddr_in*) &ha->netmask,
+						(struct sockaddr_in*) &ha->netaddr))
+				continue;
+			break;
+		case AF_INET6:
+			if (!test_mask_ipv6((struct sockaddr_in6*) sa,
+						(struct sockaddr_in6*) &ha->netmask,
+						(struct sockaddr_in6*) &ha->netaddr) ||
+					!test_scope_ipv6((struct sockaddr_in6*) sa,
+						(struct sockaddr_in6*) &ha->netmask,
+						(struct sockaddr_in6*) &ha->netaddr))
+				/* Damn I hate those casts. */
+				continue;
+			break;
+		default:
+			ast_log(LOG_WARNING, "Unhandled address family: %uh\n",
+					sa->sa_family);
+		}
+
+		/* Apply matching rule. */
+		res = ha->sense;
 	}
 	return res;
 }
 
-int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service)
-{
-	struct hostent *hp;
-	struct ast_hostent ahp;
+int ast_get_ip_or_srv(struct sockaddr *sa, socklen_t *sa_len, const char *value, const char *service)
+{
 	char srv[256];
-	char host[256];
-	int tportno = ntohs(sin->sin_port);
+	char host[NI_MAXHOST];
+	int tportno = ast_vinetsock_sa_getport(sa, *sa_len);
+	if (ast_vinetsock_sa_fromstr(value, NULL, sa, sa_len, AF_UNSPEC, 0))
+		return 0;
 	if (service) {
 		snprintf(srv, sizeof(srv), "%s.%s", service, value);
 		if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
-			sin->sin_port = htons(tportno);
 			value = host;
 		}
 	}
 
-	hp = ast_gethostbyname(value, &ahp);
-	if (hp) {
-		memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
-	} else {
+	if (ast_vinetsock_sa_fromstr(value, NULL, sa, sa_len, AF_UNSPEC, 0)) {
 		ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
 		return -1;
 	}
+	ast_vinetsock_sa_setport(sa, tportno);
 	return 0;
 }
 
@@ -317,9 +402,9 @@
 	return "unknown";
 }
 
-int ast_get_ip(struct sockaddr_in *sin, const char *value)
-{
-	return ast_get_ip_or_srv(sin, value, NULL);
+int ast_get_ip(struct sockaddr *sa, socklen_t *sa_len, const char *value)
+{
+        return ast_get_ip_or_srv((struct sockaddr*)sa, sa_len, value, NULL);
 }
 
 int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
@@ -378,43 +463,3 @@
 		return 0;
 	return -1;
 }
-
-
-
-/* IP version independent (IPv4 and IPv6) version of ACL 
- * using a new namespace to avoid conflict with current code
- * so any channel and module can transition to IPv6 one at a time.
- * duplicate code however is not automatically synched with changes above 
- *
- * \author Marc Blanchet <marc.blanchet at viagenie.ca>
- * Copyright (C) 2007, Viagenie, Inc.
- */
-#include "asterisk/netsock.h"
-
-int ast_viget_ip_or_srv(struct sockaddr *sa, socklen_t *sa_len, const char *value, const char *service)
-{
-	char srv[256];
-	char host[NI_MAXHOST];
-	int tportno = ast_vinetsock_sa_getport(sa, *sa_len);
-	if (ast_vinetsock_sa_fromstr(value, NULL, sa, sa_len, AF_UNSPEC, 0))
-		return 0;
-	if (service) {
-		snprintf(srv, sizeof(srv), "%s.%s", service, value);
-		if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
-			value = host;
-		}
-	}
-
-	if (ast_vinetsock_sa_fromstr(value, NULL, sa, sa_len, AF_UNSPEC, 0)) {
-		ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
-		return -1;
-	}
-	ast_vinetsock_sa_setport(sa, tportno);
-	return 0;
-}
-
-int ast_viget_ip(struct sockaddr *sa, socklen_t *sa_len, const char *value)
-{
-        return ast_viget_ip_or_srv((struct sockaddr*)sa, sa_len, value, NULL);
-}
-

Modified: team/group/v6/trunk/main/manager.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/main/manager.c?view=diff&rev=84406&r1=84405&r2=84406
==============================================================================
--- team/group/v6/trunk/main/manager.c (original)
+++ team/group/v6/trunk/main/manager.c Tue Oct  2 13:42:44 2007
@@ -1061,7 +1061,7 @@
 	}
 
 	if (ha) {
-		int good = ast_apply_ha(ha, &(s->sin));
+		int good = ast_apply_ha(ha, (struct sockaddr*) &s->sin, sizeof(s->sin));
 		ast_free_ha(ha);
 		if (!good) {
 			ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);




More information about the asterisk-commits mailing list