From 01a79e3adc271f6b286615e7cad32eb9618c2483 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Sun, 4 May 2003 05:52:52 +0000 Subject: [PATCH] Merge tilghman's updates for getourip git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@958 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CREDITS | 2 + acl.c | 103 +++++++++++++++++++++++++++++++++++++++++ channels/chan_mgcp.c | 103 ++--------------------------------------- channels/chan_sip.c | 106 ++++++------------------------------------- 4 files changed, 123 insertions(+), 191 deletions(-) diff --git a/CREDITS b/CREDITS index 13c4d5ad71..d8fe29b631 100755 --- 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 6a4f4fdaa0..a6c8ccb170 100755 --- a/acl.c +++ b/acl.c @@ -24,6 +24,10 @@ #include #include #include +#include +#include +#include +#include #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= 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; +} + + diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 43afb52401..a49461e8ae 100755 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -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;ipvt->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; } diff --git a/channels/chan_sip.c b/channels/chan_sip.c index e47a4ffc29..0d5449d00b 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -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;isa, 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)