From da93b546873642551379bc9ebc1cf1da9cc70f70 Mon Sep 17 00:00:00 2001
From: Martin Pycko <martinp@digium.com>
Date: Fri, 31 Oct 2003 16:13:49 +0000
Subject: [PATCH] Add externip keyword so that it's possible to use asterisk
 behind a NAT through port forwarding

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1681 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/chan_sip.c     | 42 ++++++++++++++++++++++++++---------------
 configs/sip.conf.sample |  1 +
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5427977aef..211f0eb952 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -387,7 +387,7 @@ static struct sip_registry *registrations;
 static int sipsock  = -1;
 static int globalnat = 0;
 static int globalcanreinvite = REINVITE_INVITE;
-
+static int use_external_ip = 0;
 
 static struct sockaddr_in bindaddr;
 
@@ -425,10 +425,14 @@ static void sip_destroy(struct sip_pvt *p);
 
 static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us)
 {
-	if (bindaddr.sin_addr.s_addr)
-		memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr));
-	else
-		return ast_ouraddrfor(them, us);
+	if (use_external_ip) {
+		return -1;
+	} else {
+		if (bindaddr.sin_addr.s_addr)
+			memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr));
+		else
+			return ast_ouraddrfor(them, us);
+		}
 	return 0;
 }
 
@@ -2985,7 +2989,7 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth, char
 		strncpy(p->username, r->username, sizeof(p->username)-1);
 		strncpy(p->exten, r->contact, sizeof(p->exten) - 1);
 		/* Always bind to our IP if specified */
-		if (bindaddr.sin_addr.s_addr)
+		if (!use_external_ip && bindaddr.sin_addr.s_addr)
 			memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip));
 		build_contact(p);
 	}
@@ -5979,6 +5983,13 @@ static int reload_config(void)
 			} else {
 				memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
 			}
+		} else if (!strcasecmp(v->name, "externip")) {
+			if (!(hp = gethostbyname(v->value))) {
+				ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
+			} else {
+				memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
+				use_external_ip = 1;
+			}
 		} else if (!strcasecmp(v->name, "allow")) {
 			format = ast_getformatbyname(v->value);
 			if (format < 1) 
@@ -6053,16 +6064,17 @@ static int reload_config(void)
 		}
 		cat = ast_category_browse(cfg, cat);
 	}
-	
-	if (ntohl(bindaddr.sin_addr.s_addr)) {
-		memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
-	} else {
-		hp = gethostbyname(ourhost);
-		if (!hp) {
-			ast_log(LOG_WARNING, "Unable to get IP address for %s, SIP disabled\n", ourhost);
-			return 0;
+	if (!use_external_ip) {	
+		if (ntohl(bindaddr.sin_addr.s_addr)) {
+			memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
+		} else {
+			hp = gethostbyname(ourhost);
+			if (!hp) {
+				ast_log(LOG_WARNING, "Unable to get IP address for %s, SIP disabled\n", ourhost);
+				return 0;
+			}
+			memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
 		}
-		memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
 	}
 	if (!ntohs(bindaddr.sin_port))
 		bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT);
diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
index 99337b8b72..dcfc1fd6bb 100755
--- a/configs/sip.conf.sample
+++ b/configs/sip.conf.sample
@@ -4,6 +4,7 @@
 [general]
 port = 5060			; Port to bind to
 bindaddr = 0.0.0.0		; Address to bind to
+externip = 200.201.202.203	; Address that we're going to put in SIP messages if we're behind a NAT
 context = default		; Default for incoming calls
 ;srvlookup = yes		; Enable SRV lookups on outbound calls
 ;pedantic = yes			; Enable slow, pedantic checking for Pingtel
-- 
GitLab