00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <pthread.h>
00017 #include <string.h>
00018 #include <sys/time.h>
00019 #include <signal.h>
00020 #include <errno.h>
00021 #include <unistd.h>
00022 #include <asterisk/acl.h>
00023 #include <asterisk/logger.h>
00024 #include <arpa/inet.h>
00025 #include <sys/socket.h>
00026 #include <netdb.h>
00027 #include <net/if.h>
00028 #include <netinet/in_systm.h>
00029 #include <netinet/ip.h>
00030 #include <sys/ioctl.h>
00031
00032 #define AST_SENSE_DENY 0
00033 #define AST_SENSE_ALLOW 1
00034
00035 struct ast_ha {
00036
00037 struct in_addr netaddr;
00038 struct in_addr netmask;
00039 int sense;
00040 struct ast_ha *next;
00041 };
00042
00043
00044 static struct in_addr __ourip = { 0x00000000 };
00045
00046 struct my_ifreq {
00047 char ifrn_name[IFNAMSIZ];
00048 struct sockaddr_in ifru_addr;
00049 };
00050
00051 void ast_free_ha(struct ast_ha *ha)
00052 {
00053 struct ast_ha *hal;
00054 while(ha) {
00055 hal = ha;
00056 ha = ha->next;
00057 free(hal);
00058 }
00059 }
00060
00061 struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path)
00062 {
00063 struct ast_ha *ha = malloc(sizeof(struct ast_ha));
00064 char *nm;
00065 struct ast_ha *prev = NULL;
00066 struct ast_ha *ret;
00067 ret = path;
00068 while(path) {
00069 prev = path;
00070 path = path->next;
00071 }
00072 if (ha) {
00073 char *stringp=NULL;
00074 stringp=stuff;
00075 strsep(&stringp, "/");
00076 nm = strsep(&stringp, "/");
00077 if (!nm)
00078 nm = "255.255.255.255";
00079 if (!inet_aton(stuff, &ha->netaddr)) {
00080 ast_log(LOG_WARNING, "%s not a valid IP\n", stuff);
00081 free(ha);
00082 return NULL;
00083 }
00084 if (!inet_aton(nm, &ha->netmask)) {
00085 ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
00086 free(ha);
00087 return NULL;
00088 }
00089 ha->netaddr.s_addr &= ha->netmask.s_addr;
00090 if (!strncasecmp(sense, "p", 1)) {
00091 ha->sense = AST_SENSE_ALLOW;
00092 } else {
00093 ha->sense = AST_SENSE_DENY;
00094 }
00095 ha->next = NULL;
00096 if (prev)
00097 prev->next = ha;
00098 else
00099 ret = ha;
00100 }
00101 return ret;
00102 }
00103
00104 int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
00105 {
00106
00107 int res = AST_SENSE_ALLOW;
00108 while(ha) {
00109
00110
00111 if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr))
00112 res = ha->sense;
00113 ha = ha->next;
00114 }
00115 return res;
00116 }
00117
00118 int ast_get_ip(struct sockaddr_in *sin, char *value)
00119 {
00120 struct hostent *hp;
00121 hp = gethostbyname(value);
00122 if (hp) {
00123 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
00124 } else {
00125 ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
00126 return -1;
00127 }
00128 return 0;
00129 }
00130
00131 int inaddrcmp(struct sockaddr_in *sin1, struct sockaddr_in *sin2)
00132 {
00133 return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr )
00134 || (sin1->sin_port != sin2->sin_port));
00135 }
00136
00137
00138 int ast_lookup_iface(char *iface, struct in_addr *address) {
00139 int mysock, res = 0;
00140 struct my_ifreq ifreq;
00141
00142 memset(&ifreq, 0, sizeof(ifreq));
00143 strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1);
00144
00145 mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
00146 res = ioctl(mysock,SIOCGIFADDR,&ifreq);
00147
00148 close(mysock);
00149 if (res < 0) {
00150 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
00151 memcpy((char *)address,(char *)&__ourip,sizeof(__ourip));
00152 return -1;
00153 } else {
00154 memcpy((char *)address,(char *)&ifreq.ifru_addr.sin_addr,sizeof(ifreq.ifru_addr.sin_addr));
00155 return 0;
00156 }
00157 }
00158
00159 int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
00160 {
00161 FILE *PROC;
00162 unsigned int remote_ip;
00163 int res = 1;
00164 char line[256];
00165 remote_ip = them->s_addr;
00166
00167 PROC = fopen("/proc/net/route","r");
00168 if (!PROC) {
00169 bzero(us,sizeof(struct in_addr));
00170 return -1;
00171 }
00172
00173 fgets(line,sizeof(line),PROC);
00174
00175 while (!feof(PROC)) {
00176 char iface[8];
00177 unsigned int dest, gateway, mask;
00178 int i,fieldnum;
00179 char *fields[40];
00180
00181 fgets(line,sizeof(line),PROC);
00182
00183 fieldnum = 0;
00184 for (i=0;i<sizeof(line);i++) {
00185 char *offset;
00186
00187 fields[fieldnum++] = line + i;
00188 offset = strchr(line + i,'\t');
00189 if (offset == NULL) {
00190
00191 break;
00192 } else if (fieldnum >= 9) {
00193
00194 break;
00195 } else {
00196 *offset = '\0';
00197 i = offset - line;
00198 }
00199 }
00200
00201 sscanf(fields[0],"%s",iface);
00202 sscanf(fields[1],"%x",&dest);
00203 sscanf(fields[2],"%x",&gateway);
00204 sscanf(fields[7],"%x",&mask);
00205 #if 0
00206 printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
00207 #endif
00208
00209 if (((remote_ip & mask) ^ dest) == 0) {
00210 res = ast_lookup_iface(iface,us);
00211 break;
00212 }
00213 }
00214 fclose(PROC);
00215 if (res == 1) {
00216 ast_log(LOG_WARNING, "Yikes! No default route?!!\n");
00217 bzero(us,sizeof(struct in_addr));
00218 return -2;
00219 } else if (res) {
00220
00221 return -1;
00222 }
00223 return 0;
00224 }
00225
00226