Merge tilghman's updates for getourip
authorMark Spencer <markster@digium.com>
Sun, 4 May 2003 05:52:52 +0000 (05:52 +0000)
committerMark Spencer <markster@digium.com>
Sun, 4 May 2003 05:52:52 +0000 (05:52 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@958 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CREDITS
acl.c
channels/chan_mgcp.c
channels/chan_sip.c

diff --git a/CREDITS b/CREDITS
index 13c4d5a..d8fe29b 100755 (executable)
--- a/CREDITS
+++ b/CREDITS
@@ -41,6 +41,8 @@ Mahmut Fettahlioglu - Audio recording, music-on-hold changes, alaw file
        format, and various fixes. Can be contacted at mahmut@oa.com.au
 James Dennis - Cisco SIP compatibility patches to work with SIP service
        providers. Can be contacted at asterisk@jdennis.net
+Tilghman Lesher - Route lookup code, gotoiftime application, and various
+       other patches.  http://asterisk.drunkcoder.com/
 
 === OTHER CONTRIBUTIONS ===
 John Todd - Monkey sounds and associated teletorture prompt
diff --git a/acl.c b/acl.c
index 6a4f4fd..a6c8ccb 100755 (executable)
--- a/acl.c
+++ b/acl.c
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <sys/ioctl.h>
 
 #define AST_SENSE_DENY                 0
 #define AST_SENSE_ALLOW                        1
@@ -36,6 +40,14 @@ struct ast_ha {
        struct ast_ha *next;
 };
 
+/* Default IP - if not otherwise set, don't breathe garbage */
+static struct in_addr __ourip = { (in_addr_t)0x00000000 };
+
+struct my_ifreq {
+       char ifrn_name[IFNAMSIZ];       /* Interface name, e.g. "eth0", "ppp0", etc.  */
+       struct sockaddr_in ifru_addr;
+};
+
 void ast_free_ha(struct ast_ha *ha)
 {
        struct ast_ha *hal;
@@ -121,3 +133,94 @@ int inaddrcmp(struct sockaddr_in *sin1, struct sockaddr_in *sin2)
        return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr )
                        || (sin1->sin_port != sin2->sin_port));
 }
+
+/* iface is the interface (e.g. eth0); address is the return value */
+int ast_lookup_iface(char *iface, struct in_addr *address) {
+       int mysock, res = 0;
+       struct my_ifreq ifreq;
+
+       memset(&ifreq, 0, sizeof(ifreq));
+       strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1);
+
+       mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
+       res = ioctl(mysock,SIOCGIFADDR,&ifreq);
+
+       close(mysock);
+       if (res < 0) {
+               ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
+               strncpy((char *)address,(char *)&__ourip,sizeof(__ourip));
+               return -1;
+       } else {
+               strncpy((char *)address,(char *)&ifreq.ifru_addr.sin_addr,sizeof(ifreq.ifru_addr.sin_addr));
+               return 0;
+       }
+}
+
+int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
+{
+       FILE *PROC;
+       unsigned int remote_ip;
+       int res = 1;
+       char line[256];
+       remote_ip = them->s_addr;
+       
+       PROC = fopen("/proc/net/route","r");
+       if (!PROC) {
+               bzero(us,sizeof(struct in_addr));
+               return -1;
+       }
+       /* First line contains headers */
+       fgets(line,sizeof(line),PROC);
+
+       while (!feof(PROC)) {
+               char iface[8];
+               unsigned int dest, gateway, mask;
+               int i,fieldnum;
+               char *fields[40];
+
+               fgets(line,sizeof(line),PROC);
+
+               fieldnum = 0;
+               for (i=0;i<sizeof(line);i++) {
+                       char *offset;
+
+                       fields[fieldnum++] = line + i;
+                       offset = strchr(line + i,'\t');
+                       if (offset == NULL) {
+                               /* Exit loop */
+                               break;
+                       } else if (fieldnum >= 9) {
+                               /* Short-circuit: can't break at 8, since the end of field 7 is figured when fieldnum=8 */
+                               break;
+                       } else {
+                               *offset = '\0';
+                               i = offset - line;
+                       }
+               }
+
+               sscanf(fields[0],"%s",iface);
+               sscanf(fields[1],"%x",&dest);
+               sscanf(fields[2],"%x",&gateway);
+               sscanf(fields[7],"%x",&mask);
+#if 0
+               printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
+#endif         
+               /* Looks simple, but here is the magic */
+               if (((remote_ip & mask) ^ dest) == 0) {
+                       res = ast_lookup_iface(iface,us);
+                       break;
+               }
+       }
+       fclose(PROC);
+       if (res == 1) {
+               ast_log(LOG_WARNING, "Yikes!  No default route?!!\n");
+               bzero(us,sizeof(struct in_addr));
+               return -2;
+       } else if (res) {
+               /* We've already warned in subroutine */
+               return -1;
+       }
+       return 0;
+}
+
+
index 43afb52..a49461e 100755 (executable)
@@ -278,103 +278,6 @@ static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
        return res;
 }
 
-/* Interface lookup code courtesy Tilghman of DrunkCoder.com.  Thanks! */
-
-struct my_ifreq {
-    union
-      {
-       char ifrn_name[IFNAMSIZ];       /* Interface name, e.g. "en0".  */
-      } ifr_ifrn;
-
-    union
-      {
-       struct sockaddr_in ifru_addr;
-       char ifru_data[512];
-      } ifr_ifru;
-};
-
-static struct in_addr *lookup_iface(char *iface) {
-       int mysock;
-       int res;
-       static struct  my_ifreq ifreq;
-       strncpy(ifreq.ifr_ifrn.ifrn_name,iface,sizeof(ifreq.ifr_ifrn.ifrn_name));
-
-       mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
-       res = ioctl(mysock,SIOCGIFADDR,&ifreq);
-       
-       close(mysock);
-       if (res < 0) {
-               ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
-               return &__ourip;
-       }
-       return( (struct in_addr *) &ifreq.ifr_ifru.ifru_addr.sin_addr );
-}
-
-static struct in_addr *myaddrfor(struct in_addr *them)
-{
-       FILE *PROC;
-       struct in_addr *temp = NULL;
-       unsigned int remote_ip;
-       char line[256];
-       remote_ip = them->s_addr;
-       
-       PROC = fopen("/proc/net/route","r");
-       if (!PROC) {
-               /* If /proc/net/route doesn't exist, fall back to the old method */
-               return &__ourip;
-       }
-       /* First line contains headers */
-       fgets(line,sizeof(line),PROC);
-
-       while (!feof(PROC)) {
-               char iface[8];
-               unsigned int dest, gateway, mask;
-               int i,aoffset;
-               char *fields[40];
-
-               fgets(line,sizeof(line),PROC);
-
-               aoffset = 0;
-               for (i=0;i<sizeof(line);i++) {
-                       char *boffset;
-
-                       fields[aoffset++] = line + i;
-                       boffset = strchr(line + i,'\t');
-                       if (boffset == NULL) {
-                               /* Exit loop */
-                               break;
-                       } else {
-                               *boffset = '\0';
-                               i = boffset - line;
-                       }
-               }
-
-               sscanf(fields[0],"%s",iface);
-               sscanf(fields[1],"%x",&dest);
-               sscanf(fields[2],"%x",&gateway);
-               sscanf(fields[7],"%x",&mask);
-#if 0
-               printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
-#endif         
-               if (((remote_ip & mask) ^ dest) == 0) {
-
-                       if (mgcpdebug)
-                                       ast_verbose("Interface is %s\n",iface);
-                       temp = lookup_iface(iface);
-                       if (mgcpdebug)
-                               ast_verbose("IP Address is %s\n",inet_ntoa(*temp));
-                       break;
-               }
-       }
-       fclose(PROC);
-       if (!temp) {
-               ast_log(LOG_WARNING, "Couldn't figure out how to get to %s.  Using default\n", inet_ntoa(*them));
-               temp = &__ourip;
-       }
-       return temp;
-}
-
-
 static int mgcp_hangup(struct ast_channel *ast)
 {
        struct mgcp_endpoint *p = ast->pvt->pvt;
@@ -808,7 +711,8 @@ static struct mgcp_endpoint *find_endpoint(char *name, int msgid, struct sockadd
                                if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
                                        (g->addr.sin_port != sin->sin_port)) {
                                        memcpy(&g->addr, sin, sizeof(g->addr));
-                                       memcpy(&g->ourip, myaddrfor(&g->addr.sin_addr), sizeof(g->ourip));
+                                       if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip))
+                                               memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
                                        if (option_verbose > 2)
                                                ast_verbose(VERBOSE_PREFIX_3 "Registered MGCP gateway '%s' at %s port %d\n", g->name, inet_ntoa(g->addr.sin_addr), ntohs(g->addr.sin_port));
                                }
@@ -1793,7 +1697,8 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
        if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port))
                gw->addr.sin_port = htons(DEFAULT_MGCP_PORT);
        if (gw->addr.sin_addr.s_addr)
-               memcpy(&gw->ourip, myaddrfor(&gw->addr.sin_addr), sizeof(gw->ourip));
+               if (ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip))
+                       memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
        return gw;
 }
 
index e47a4ff..0d5449d 100755 (executable)
@@ -35,6 +35,7 @@
 #include <asterisk/musiconhold.h>
 #include <asterisk/dsp.h>
 #include <asterisk/parking.h>
+#include <asterisk/acl.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
@@ -844,94 +845,6 @@ static void sip_destroy(struct sip_pvt *p)
        ast_pthread_mutex_unlock(&iflock);
 }
 
-/* Interface lookup code courtesy Tilghman of DrunkCoder.com.  Thanks! */
-
-struct my_ifreq {
-       char ifrn_name[IFNAMSIZ];       /* Interface name, e.g. "en0".  */
-       struct sockaddr_in ifru_addr;
-};
-
-static struct in_addr *lookup_iface(char *iface) {
-       int mysock;
-       int res;
-       static struct  my_ifreq ifreq;
-       memset(&ifreq, 0, sizeof(ifreq));
-       strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1);
-
-       mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
-       res = ioctl(mysock,SIOCGIFADDR,&ifreq);
-       
-       close(mysock);
-       if (res < 0) {
-               ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
-               return &__ourip;
-       }
-       return( (struct in_addr *) &ifreq.ifru_addr.sin_addr );
-}
-
-static struct in_addr *myaddrfor(struct in_addr *them)
-{
-       FILE *PROC;
-       struct in_addr *temp = NULL;
-       unsigned int remote_ip;
-       char line[256];
-       remote_ip = them->s_addr;
-       
-       PROC = fopen("/proc/net/route","r");
-       if (!PROC) {
-               /* If /proc/net/route doesn't exist, fall back to the old method */
-               return &__ourip;
-       }
-       /* First line contains headers */
-       fgets(line,sizeof(line),PROC);
-
-       while (!feof(PROC)) {
-               char iface[8];
-               unsigned int dest, gateway, mask;
-               int i,aoffset;
-               char *fields[40];
-
-               fgets(line,sizeof(line),PROC);
-
-               aoffset = 0;
-               for (i=0;i<sizeof(line);i++) {
-                       char *boffset;
-
-                       fields[aoffset++] = line + i;
-                       boffset = strchr(line + i,'\t');
-                       if (boffset == NULL) {
-                               /* Exit loop */
-                               break;
-                       } else {
-                               *boffset = '\0';
-                               i = boffset - line;
-                       }
-               }
-
-               sscanf(fields[0],"%s",iface);
-               sscanf(fields[1],"%x",&dest);
-               sscanf(fields[2],"%x",&gateway);
-               sscanf(fields[7],"%x",&mask);
-#if 0
-               printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
-#endif         
-               if (((remote_ip & mask) ^ dest) == 0) {
-                       if (sipdebug)
-                               ast_verbose("Interface is %s\n",iface);
-                       temp = lookup_iface(iface);
-                       if (sipdebug)
-                               ast_verbose("IP Address is %s\n",inet_ntoa(*temp));
-                       break;
-               }
-       }
-       fclose(PROC);
-       if (!temp) {
-               ast_log(LOG_WARNING, "Couldn't figure out how to get to %s.  Using default\n", inet_ntoa(*them));
-               temp = &__ourip;
-       }
-       return temp;
-}
-
 static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req);
 
 
@@ -1363,10 +1276,12 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
 #endif 
        if (sin) {
                memcpy(&p->sa, sin, sizeof(p->sa));
-               memcpy(&p->ourip, myaddrfor(&p->sa.sin_addr), sizeof(p->ourip));
+               if (ast_ouraddrfor(&p->sa.sin_addr,&p->ourip))
+                       memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
        } else {
                memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
        }
+       /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
        snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch);
        if (!callid)
                build_callid(p->callid, sizeof(p->callid), p->ourip);
@@ -2668,6 +2583,7 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth)
        snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, cmd);
        p->ocseq = r->ocseq;
 
+       /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
        snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch);
        add_header(&req, "Via", via);
        add_header(&req, "From", from);
@@ -4595,7 +4511,9 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
                return 0;
        }
        /* Recalculate our side, and recalculate Call ID */
-       memcpy(&p->ourip, myaddrfor(&p->sa.sin_addr), sizeof(p->ourip));
+       if (ast_ouraddrfor(&p->sa.sin_addr,&p->ourip))
+               memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+       /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
        snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch);
        build_callid(p->callid, sizeof(p->callid), p->ourip);
        /* Send MWI */
@@ -4746,7 +4664,9 @@ static int sip_poke_peer(struct sip_peer *peer)
                snprintf(p->tohost, sizeof(p->tohost), "%s", inet_ntoa(peer->addr.sin_addr));
 
        /* Recalculate our side, and recalculate Call ID */
-       memcpy(&p->ourip, myaddrfor(&p->sa.sin_addr), sizeof(p->ourip));
+       if (ast_ouraddrfor(&p->sa.sin_addr,&p->ourip))
+               memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+       /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
        snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch);
        build_callid(p->callid, sizeof(p->callid), p->ourip);
 
@@ -4855,7 +4775,9 @@ static struct ast_channel *sip_request(char *type, int format, void *data)
        if (!strlen(p->peername) && ext)
                strncpy(p->peername, ext, sizeof(p->peername) - 1);
        /* Recalculate our side, and recalculate Call ID */
-       memcpy(&p->ourip, myaddrfor(&p->sa.sin_addr), sizeof(p->ourip));
+       if (ast_ouraddrfor(&p->sa.sin_addr,&p->ourip))
+               memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+       /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
        snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch);
        build_callid(p->callid, sizeof(p->callid), p->ourip);
        if (ext)