Index: include/asterisk/security_events_defs.h
===================================================================
--- include/asterisk/security_events_defs.h	(revision 357541)
+++ include/asterisk/security_events_defs.h	(working copy)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2009, Digium, Inc.
+ * Copyright (C) 2012, Digium, Inc.
  *
  * Russell Bryant <russell@digium.com>
  *
@@ -151,8 +151,8 @@
 
 #define AST_SEC_EVT(e) ((struct ast_security_event_common *) e)
 
-struct ast_security_event_ipv4_addr {
-	const struct sockaddr_in *sin;
+struct ast_security_event_ip_addr {
+	const struct ast_sockaddr *addr;
 	enum ast_security_event_transport_type transport;
 };
 
@@ -202,12 +202,12 @@
 	 * \brief Local address the request came in on
 	 * \note Always required
 	 */
-	struct ast_security_event_ipv4_addr local_addr;
+	struct ast_security_event_ip_addr local_addr;
 	/*!
 	 * \brief Remote address the request came from
 	 * \note Always required
 	 */
-	struct ast_security_event_ipv4_addr remote_addr;
+	struct ast_security_event_ip_addr remote_addr;
 };
 
 /*!
@@ -418,7 +418,7 @@
 	 * \brief Event descriptor version
 	 * \note This _must_ be changed if this event descriptor is changed.
 	 */
-	#define AST_SECURITY_EVENT_UNEXPECTED_ADDR_VERSION 1
+	#define AST_SECURITY_EVENT_UNEXPECTED_ADDR_VERSION 2
 	/*!
 	 * \brief Common security event descriptor elements
 	 * \note Account ID required
@@ -428,7 +428,7 @@
 	 * \brief Expected remote address
 	 * \note required
 	 */
-	struct ast_security_event_ipv4_addr expected_addr;
+	struct ast_security_event_ip_addr expected_addr;
 };
 
 /*!
Index: CHANGES
===================================================================
--- CHANGES	(revision 357541)
+++ CHANGES	(working copy)
@@ -964,6 +964,8 @@
    Asterisk component that reports security events.  However, SIP support will be
    coming soon.  For more information on the security events framework, see the
    "Security Events" chapter of the included documentation - doc/tex/asterisk.pdf.
+ * SIP support was added in Asterisk 10
+ * This API now supports IPv6 addresses
 
 Fax
 ---
Index: channels/sip/security_events.c
===================================================================
--- channels/sip/security_events.c	(revision 357541)
+++ channels/sip/security_events.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2011, Digium, Inc.
+ * Copyright (C) 2012, Digium, Inc.
  *
  * Michael L. Young <elgueromexicano@gmail.com>
  *
@@ -49,25 +49,9 @@
 	return res;
 }
 
-static struct sockaddr_in *security_event_encode_sin_local(const struct sip_pvt *p, struct sockaddr_in *sin_local)
-{
-	ast_sockaddr_to_sin(&p->ourip, sin_local);
-
-	return sin_local;
-}
-
-static struct sockaddr_in *security_event_encode_sin_remote(const struct sip_pvt *p, struct sockaddr_in *sin_remote)
-{
-        ast_sockaddr_to_sin(&p->sa, sin_remote);
-
-        return sin_remote;
-}
-
 void sip_report_invalid_peer(const struct sip_pvt *p)
 {
 	char session_id[32];
-	struct sockaddr_in sin_local;
-	struct sockaddr_in sin_remote;
 
 	struct ast_security_event_inval_acct_id inval_acct_id = {
 		.common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
@@ -75,11 +59,11 @@
 		.common.service    = "SIP",
 		.common.account_id = p->exten,
 		.common.local_addr = {
-			.sin       = security_event_encode_sin_local(p, &sin_local),
+			.addr      = &p->ourip,
 			.transport = security_event_get_transport(p)
 		},
 		.common.remote_addr = {
-			.sin       = security_event_encode_sin_remote(p, &sin_remote),
+			.addr       = &p->sa,
 			.transport = security_event_get_transport(p)
 		},
 		.common.session_id = session_id,
@@ -93,8 +77,6 @@
 void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname)
 {
         char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
 
         struct ast_security_event_failed_acl failed_acl_event = {
                 .common.event_type  = AST_SECURITY_EVENT_FAILED_ACL,
@@ -102,11 +84,11 @@
                 .common.service     = "SIP",
                 .common.account_id  = p->exten,
                 .common.local_addr  = {
-                        .sin        = security_event_encode_sin_local(p, &sin_local),
+                        .addr       = &p->ourip,
                         .transport  = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin        = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr       = &p->sa,
                         .transport  = security_event_get_transport(p)
                 },
                 .common.session_id  = session_id,
@@ -121,8 +103,6 @@
 void sip_report_inval_password(const struct sip_pvt *p, const char *response_challenge, const char *response_hash)
 {
         char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
 
         struct ast_security_event_inval_password inval_password = {
                 .common.event_type  = AST_SECURITY_EVENT_INVAL_PASSWORD,
@@ -130,11 +110,11 @@
                 .common.service     = "SIP",
                 .common.account_id  = p->exten,
                 .common.local_addr  = {
-                        .sin        = security_event_encode_sin_local(p, &sin_local),
+                        .addr       = &p->ourip,
                         .transport  = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin        = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr       = &p->sa,
                         .transport  = security_event_get_transport(p)
                 },
                 .common.session_id  = session_id,
@@ -152,8 +132,6 @@
 void sip_report_auth_success(const struct sip_pvt *p, uint32_t *using_password)
 {
         char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
 
         struct ast_security_event_successful_auth successful_auth = {
                 .common.event_type  = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
@@ -161,11 +139,11 @@
                 .common.service     = "SIP",
                 .common.account_id  = p->exten,
                 .common.local_addr  = {
-                        .sin        = security_event_encode_sin_local(p, &sin_local),
+                        .addr       = &p->ourip,
                         .transport  = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin        = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr       = &p->sa,
                         .transport  = security_event_get_transport(p)
                 },
                 .common.session_id  = session_id,
@@ -180,8 +158,6 @@
 void sip_report_session_limit(const struct sip_pvt *p)
 {
         char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
 
         struct ast_security_event_session_limit session_limit = {
                 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
@@ -189,11 +165,11 @@
                 .common.service    = "SIP",
                 .common.account_id = p->exten,
                 .common.local_addr = {
-                        .sin       = security_event_encode_sin_local(p, &sin_local),
+                        .addr      = &p->ourip,
                         .transport = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin       = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr      = &p->sa,
                         .transport = security_event_get_transport(p)
                 },
                 .common.session_id = session_id,
@@ -206,9 +182,7 @@
 
 void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response)
 {
-        char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
+	char session_id[32];
 	char account_id[256];
 
 	struct ast_security_event_chal_resp_failed chal_resp_failed = {
@@ -217,11 +191,11 @@
                 .common.service    = "SIP",
                 .common.account_id = account_id,
                 .common.local_addr = {
-                        .sin       = security_event_encode_sin_local(p, &sin_local),
+                        .addr      = &p->ourip,
                         .transport = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin       = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr      = &p->sa,
                         .transport = security_event_get_transport(p)
                 },
                 .common.session_id = session_id,
@@ -244,22 +218,20 @@
 
 void sip_report_chal_sent(const struct sip_pvt *p)
 {
-        char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
+	char session_id[32];
 	char account_id[256];
 
-        struct ast_security_event_chal_sent chal_sent = {
+	struct ast_security_event_chal_sent chal_sent = {
                 .common.event_type = AST_SECURITY_EVENT_CHAL_SENT,
                 .common.version    = AST_SECURITY_EVENT_CHAL_SENT_VERSION,
                 .common.service    = "SIP",
                 .common.account_id = account_id,
                 .common.local_addr = {
-                        .sin       = security_event_encode_sin_local(p, &sin_local),
+                        .addr      = &p->ourip,
                         .transport = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin       = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr      = &p->sa,
                         .transport = security_event_get_transport(p)
                 },
                 .common.session_id = session_id,
@@ -281,8 +253,6 @@
 void sip_report_inval_transport(const struct sip_pvt *p, const char *transport)
 {
         char session_id[32];
-        struct sockaddr_in sin_local;
-        struct sockaddr_in sin_remote;
 
         struct ast_security_event_inval_transport inval_transport = {
                 .common.event_type = AST_SECURITY_EVENT_INVAL_TRANSPORT,
@@ -290,11 +260,11 @@
                 .common.service    = "SIP",
                 .common.account_id = p->exten,
                 .common.local_addr = {
-                        .sin       = security_event_encode_sin_local(p, &sin_local),
+                        .addr      = &p->ourip,
                         .transport = security_event_get_transport(p)
                 },
                 .common.remote_addr = {
-                        .sin       = security_event_encode_sin_remote(p, &sin_remote),
+                        .addr      = &p->sa,
                         .transport = security_event_get_transport(p)
                 },
                 .common.session_id = session_id,
Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 357541)
+++ channels/chan_sip.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2012, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -3442,7 +3442,7 @@
 	ast_sockaddr_copy(&theirs, them);
 
 	if (ast_sockaddr_is_ipv6(&theirs)) {
-		if (localaddr && !ast_sockaddr_isnull(&externaddr)) {
+		if (localaddr && !ast_sockaddr_isnull(&externaddr) && !ast_sockaddr_is_any(&bindaddr)) {
 			ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
 				"but we're using IPv6, which doesn't need it. Please "
 				"remove \"localnet\" and/or \"externaddr\" settings.\n");
Index: main/manager.c
===================================================================
--- main/manager.c	(revision 357541)
+++ main/manager.c	(working copy)
@@ -2151,18 +2151,17 @@
 			AST_SECURITY_EVENT_TRANSPORT_TCP;
 }
 
-static struct sockaddr_in *mansession_encode_sin_local(const struct mansession *s,
-		struct sockaddr_in *sin_local)
+static struct ast_sockaddr *mansession_ast_sockaddr_remote(const struct sockaddr_in *sin,
+		struct ast_sockaddr *addr_remote)
 {
-	ast_sockaddr_to_sin(&s->tcptls_session->parent->local_address,
-			    sin_local);
+	ast_sockaddr_from_sin(addr_remote, sin);
 
-	return sin_local;
+	return addr_remote;
 }
 
 static void report_invalid_user(const struct mansession *s, const char *username)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	struct ast_security_event_inval_acct_id inval_acct_id = {
 		.common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
@@ -2171,11 +2170,11 @@
 		.common.account_id = username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2188,7 +2187,7 @@
 
 static void report_failed_acl(const struct mansession *s, const char *username)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	struct ast_security_event_failed_acl failed_acl_event = {
 		.common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
@@ -2197,11 +2196,11 @@
 		.common.account_id = username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2214,7 +2213,7 @@
 
 static void report_inval_password(const struct mansession *s, const char *username)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	struct ast_security_event_inval_password inval_password = {
 		.common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
@@ -2223,11 +2222,11 @@
 		.common.account_id = username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2240,7 +2239,7 @@
 
 static void report_auth_success(const struct mansession *s)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	struct ast_security_event_successful_auth successful_auth = {
 		.common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
@@ -2249,11 +2248,11 @@
 		.common.account_id = s->session->username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2266,7 +2265,7 @@
 
 static void report_req_not_allowed(const struct mansession *s, const char *action)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	char request_type[64];
 	struct ast_security_event_req_not_allowed req_not_allowed = {
@@ -2276,11 +2275,11 @@
 		.common.account_id = s->session->username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2296,7 +2295,7 @@
 
 static void report_req_bad_format(const struct mansession *s, const char *action)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	char request_type[64];
 	struct ast_security_event_req_bad_format req_bad_format = {
@@ -2306,11 +2305,11 @@
 		.common.account_id = s->session->username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2327,7 +2326,7 @@
 static void report_failed_challenge_response(const struct mansession *s,
 		const char *response, const char *expected_response)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	struct ast_security_event_chal_resp_failed chal_resp_failed = {
 		.common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
@@ -2336,11 +2335,11 @@
 		.common.account_id = s->session->username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
@@ -2357,7 +2356,7 @@
 
 static void report_session_limit(const struct mansession *s)
 {
-	struct sockaddr_in sin_local;
+	struct ast_sockaddr addr_remote;
 	char session_id[32];
 	struct ast_security_event_session_limit session_limit = {
 		.common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
@@ -2366,11 +2365,11 @@
 		.common.account_id = s->session->username,
 		.common.session_tv = &s->session->sessionstart_tv,
 		.common.local_addr = {
-			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.addr      = &s->tcptls_session->parent->local_address,
 			.transport = mansession_get_transport(s),
 		},
 		.common.remote_addr = {
-			.sin       = &s->session->sin,
+			.addr      = mansession_ast_sockaddr_remote(&s->session->sin, &addr_remote),
 			.transport = mansession_get_transport(s),
 		},
 		.common.session_id = session_id,
Index: main/security_events.c
===================================================================
--- main/security_events.c	(revision 357541)
+++ main/security_events.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2009, Digium, Inc.
+ * Copyright (C) 2012, Digium, Inc.
  *
  * Russell Bryant <russell@digium.com>
  *
@@ -32,6 +32,7 @@
 #include "asterisk/strings.h"
 #include "asterisk/network.h"
 #include "asterisk/security_events.h"
+#include "asterisk/netsock2.h"
 
 static const size_t TIMESTAMP_STR_LEN = 32;
 
@@ -502,12 +503,14 @@
 	return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
 }
 
-static int add_ipv4_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
-		const struct ast_security_event_ipv4_addr *addr)
+static int add_ip_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
+		const struct ast_security_event_ip_addr *addr)
 {
 	struct ast_str *str = ast_str_alloca(64);
+	char *str_address;
+	char *str_port;
 
-	ast_str_set(&str, 0, "IPV4/");
+	ast_str_set(&str, 0, ast_sockaddr_is_ipv4(addr->addr) || ast_sockaddr_is_ipv4_mapped(addr->addr) ? "IPV4/" : "IPV6/");
 
 	switch (addr->transport) {
 	case AST_SECURITY_EVENT_TRANSPORT_UDP:
@@ -521,10 +524,11 @@
 		break;
 	}
 
-	ast_str_append(&str, 0, "%s/%hu",
-			ast_inet_ntoa(addr->sin->sin_addr),
-			ntohs(addr->sin->sin_port));
+	str_address = ast_strdupa(ast_sockaddr_stringify_addr(addr->addr));
+	str_port = ast_strdupa(ast_sockaddr_stringify_port(addr->addr));
 
+	ast_str_append(&str, 0, "%s/%s", str_address, str_port);
+
 	return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
 }
 
@@ -583,19 +587,19 @@
 	case AST_EVENT_IE_REMOTE_ADDR:
 	case AST_EVENT_IE_EXPECTED_ADDR:
 	{
-		const struct ast_security_event_ipv4_addr *addr;
+		const struct ast_security_event_ip_addr *addr;
 
-		addr = (const struct ast_security_event_ipv4_addr *)(((const char *) sec) + ie_type->offset);
+		addr = (const struct ast_security_event_ip_addr *)(((const char *) sec) + ie_type->offset);
 
-		if (req && !addr->sin) {
+		if (req && !addr->addr) {
 			ast_log(LOG_WARNING, "Required IE '%d' for security event "
 					"type '%d' not present\n", ie_type->ie_type,
 					sec->event_type);
 			res = -1;
 		}
 
-		if (addr->sin) {
-			res = add_ipv4_ie(event, ie_type->ie_type, addr);
+		if (addr->addr) {
+			res = add_ip_ie(event, ie_type->ie_type, addr);
 		}
 		break;
 	}
