diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-05-04 05:52:52 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-05-04 05:52:52 +0000 |
commit | 1d1eb91abab2839ad8e3cc99437b57854d37bead (patch) | |
tree | 25c09646507834e41e03b5aabe4974f2fd6724e6 /acl.c | |
parent | 07cb452269f6b46371e7bea66f3c82058230b1cb (diff) |
Merge tilghman's updates for getourip
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@958 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'acl.c')
-rwxr-xr-x | acl.c | 103 |
1 files changed, 103 insertions, 0 deletions
@@ -24,6 +24,10 @@ #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; +} + + |