Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.374 diff -u -r1.374 chan_sip.c --- channels/chan_sip.c 8 May 2004 14:45:49 -0000 1.374 +++ channels/chan_sip.c 8 May 2004 19:08:47 -0000 @@ -457,8 +457,8 @@ static struct sockaddr_in bindaddr; static struct sockaddr_in localnet; -static struct sockaddr_in localmask; static struct sockaddr_in externip; +static struct ast_ha *localaddr; static struct ast_frame *sip_read(struct ast_channel *ast); static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req); @@ -500,13 +500,19 @@ static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us) { /* - check to see if them is contained in our localnet/mask, - if not, use our externip for us, otherwise use the - real internal address in bindaddr - */ - if (localnet.sin_addr.s_addr && externip.sin_addr.s_addr && - ((htonl(them->s_addr) & htonl(localnet.sin_addr.s_addr)) != htonl(localnet.sin_addr.s_addr))) + * Using the localaddr structure built up with localnet statements + * apply it to their address to see if we need to substitute our + * externip or can get away with our internal bindaddr + */ + struct sockaddr_in theirs; + theirs.sin_addr = *them; + if (localaddr && externip.sin_addr.s_addr && + (ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW)) { + char t[256]; memcpy(us, &externip.sin_addr, sizeof(struct in_addr)); + strcpy(t, inet_ntoa(*(struct in_addr *)&them->s_addr)); + ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", t); + } else if (bindaddr.sin_addr.s_addr) memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr)); else @@ -6981,7 +6987,7 @@ memset(&bindaddr, 0, sizeof(bindaddr)); memset(&localnet, 0, sizeof(localnet)); - memset(&localmask, 0, sizeof(localmask)); + memset(&localaddr, 0, sizeof(localaddr)); memset(&externip, 0, sizeof(externip)); /* Initialize some reasonable defaults */ @@ -7053,15 +7059,13 @@ memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); } } else if (!strcasecmp(v->name, "localnet")) { - if (!(hp = ast_gethostbyname(v->value, &ahp))) - ast_log(LOG_WARNING, "Invalid localnet keyword: %s\n", v->value); - else - memcpy(&localnet.sin_addr, hp->h_addr, sizeof(localnet.sin_addr)); - } else if (!strcasecmp(v->name, "localmask")) { - if (!(hp = ast_gethostbyname(v->value, &ahp))) - ast_log(LOG_WARNING, "Invalid localmask keyword: %s\n", v->value); + struct ast_ha *na; + if (!(na = ast_append_ha("d", v->value, localaddr))) + ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); else - memcpy(&localmask.sin_addr, hp->h_addr, sizeof(localmask.sin_addr)); + localaddr = na; + } else if (!strcasecmp(v->name, "localmask")) { + ast_log(LOG_WARNING, "Use of localmask is deprecated; use localnet with mask syntax\n"); } else if (!strcasecmp(v->name, "externip")) { if (!(hp = ast_gethostbyname(v->value, &ahp))) ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); @@ -7560,6 +7564,10 @@ ast_log(LOG_WARNING, "Unable to lock the interface list\n"); return -1; } + /* Free memory for local network address mask */ + if (localaddr) { + ast_free_ha(localaddr); + } return 0; } Index: configs/sip.conf.sample =================================================================== RCS file: /usr/cvsroot/asterisk/configs/sip.conf.sample,v retrieving revision 1.26 diff -u -r1.26 sip.conf.sample --- configs/sip.conf.sample 6 May 2004 20:00:19 -0000 1.26 +++ configs/sip.conf.sample 8 May 2004 19:08:47 -0000 @@ -68,11 +68,14 @@ ;externip = 200.201.202.203 ; Address that we're going to put in outbound SIP messages ; if we're behind a NAT -;localnet = 192.168.1.0 ; Internal NETWORK address -;localmask = 255.255.255.0 ; Internal netmask - ; The externip, localnet and localmask is used - ; when registering and communication with other proxies + + ; The externip and localnet is used + ; when registering and communicating with other proxies ; that we're registered with + ; You may add multiple local networks. +localnet=192.168.0.0/255.255.0.0; All RFC 1918 addresses are local networks +localnet=10.0.0.0/255.0.0.0 ; Also RFC1918 +localnet=169.254.0.0/255.255.0.0 ;Zero conf local network ;[snomsip] ;type=friend