Merge tilghman's updates for getourip

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@958 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer
2003-05-04 05:52:52 +00:00
parent b7e5181f8e
commit 01a79e3adc
4 changed files with 123 additions and 191 deletions

103
acl.c
View File

@@ -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;
}