[Asterisk-Users] Asterisk behind nat with hole, hardcoding solution

Walter Snel spam at nachtwacht.org
Mon Oct 27 15:52:24 MST 2003


Hi,

A brief 6-step guide on how to hardcode a change in the Asterisk source that
will allow it to work from behind a nat device. I know it’s messy, but it
may prove useful to some people.

1. First punch a whole in your nat device. I just forwarded the port 5060
(for sip) and all ports between 10000 to 10020 (for rtp) to my asterisk
gateway.
2. Now make sure your /etc/asterisk/rtp.conf correctly reflects the 'rtp'
hole in the nat device (for me that's between 10000 and 10020).

Now we need to make three small changes to the file
/usr/src/asterisk/channels/chan_sip.c

3. First find the function build_contact(
) and insert your ‘outside’ ip
address in the right position, as is indicated below (the original line is
commented out):

static void build_contact(struct sip_pvt *p)
{
        /* Construct Contact: header */
        if (ourport != 5060)
                snprintf(p->our_contact, sizeof(p->our_contact),
"<sip:%s@%s:%d>", p->exten, inet_ntoa(p->ourip), ourport);
        else
//              snprintf(p->our_contact, sizeof(p->our_contact),
"<sip:%s@%s>", p->exten, inet_ntoa(p->ourip));
                snprintf(p->our_contact, sizeof(p->our_contact),
"<sip:%s at 213.84.4.39>", p->exten, inet_ntoa(p->ourip));
}

4. Now find the function add_sdp(
) and replace the variable strings with
the ‘outside’ ip address (two times) as indicated below:

        snprintf(v, sizeof(v), "v=0\r\n");
//      snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(),
getpid(), inet_ntoa(dest.sin_addr));
        snprintf(o, sizeof(o), "o=root %d %d IN IP4 213.84.4.39\r\n",
getpid(), getpid());
        snprintf(s, sizeof(s), "s=session\r\n");
//      snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", inet_ntoa(dest.sin_addr));
        snprintf(c, sizeof(c), "c=IN IP4 213.84.4.39\r\n");
        snprintf(t, sizeof(t), "t=0 0\r\n");
        snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
        snprintf(m2, sizeof(m2), "m=video %d RTP/AVP",
ntohs(vdest.sin_port));
        /* Start by sending our preferred codecs */
        cur = prefs;

5. Perform a ‘make’ in this directory, and copy the resulting ‘chan_sip.so’
file to your /usr/lib/asterisk/modules/ directory.
6. Restart asterisk.

It works for me (tested with xten softphone)

This causes Asterisk to use the outside address in all sip connections, as a
result Asterisk may become useless for sip phones on the 'inside' network.
Naturally it would be much better to make this behavior:

	1. Configurable.
	2. Dependent on something like an ip addressfilter so that only connections
for peers that are actually behind the nat (as indicated by a match with the
filter) are 'redirected' to the outside address.

With kind regards,
Walter Snel




More information about the asterisk-users mailing list