aboutsummaryrefslogtreecommitdiffstats
path: root/acl.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-05-04 05:52:52 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-05-04 05:52:52 +0000
commit1d1eb91abab2839ad8e3cc99437b57854d37bead (patch)
tree25c09646507834e41e03b5aabe4974f2fd6724e6 /acl.c
parent07cb452269f6b46371e7bea66f3c82058230b1cb (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-xacl.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/acl.c b/acl.c
index 6a4f4fdaa..a6c8ccb17 100755
--- a/acl.c
+++ b/acl.c
@@ -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;
+}
+
+