Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

acl.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <asterisk/acl.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/utils.h>
#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>

Include dependency graph for acl.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  ast_ha
struct  my_ifreq

Functions

void ast_free_ha (struct ast_ha *ha)
ast_haast_duplicate_ha_list (struct ast_ha *original)
ast_haast_append_ha (char *sense, char *stuff, struct ast_ha *path)
int ast_apply_ha (struct ast_ha *ha, struct sockaddr_in *sin)
int ast_get_ip (struct sockaddr_in *sin, char *value)
int ast_lookup_iface (char *iface, struct in_addr *address)
int ast_ouraddrfor (struct in_addr *them, struct in_addr *us)


Function Documentation

struct ast_ha* ast_append_ha char *  sense,
char *  stuff,
struct ast_ha path
 

Definition at line 113 of file acl.c.

References ast_log(), AST_SENSE_ALLOW, AST_SENSE_DENY, free, LOG_DEBUG, LOG_WARNING, malloc, and ast_ha::next.

00114 { 00115 struct ast_ha *ha = malloc(sizeof(struct ast_ha)); 00116 char *nm="255.255.255.255"; 00117 char tmp[256] = ""; 00118 struct ast_ha *prev = NULL; 00119 struct ast_ha *ret; 00120 int x,z; 00121 unsigned int y; 00122 ret = path; 00123 while(path) { 00124 prev = path; 00125 path = path->next; 00126 } 00127 if (ha) { 00128 strncpy(tmp, stuff, sizeof(tmp) - 1); 00129 nm = strchr(tmp, '/'); 00130 if (!nm) 00131 nm = "255.255.255.255"; 00132 else { 00133 *nm = '\0'; 00134 nm++; 00135 } 00136 if (!strchr(nm, '.')) { 00137 if ((sscanf(nm, "%i", &x) == 1) && (x >= 0) && (x <= 32)) { 00138 y = 0; 00139 for (z=0;z<x;z++) { 00140 y >>= 1; 00141 y |= 0x80000000; 00142 } 00143 ha->netmask.s_addr = htonl(y); 00144 } 00145 } else if (!inet_aton(nm, &ha->netmask)) { 00146 ast_log(LOG_WARNING, "%s not a valid netmask\n", nm); 00147 free(ha); 00148 return path; 00149 } 00150 if (!inet_aton(tmp, &ha->netaddr)) { 00151 ast_log(LOG_WARNING, "%s not a valid IP\n", tmp); 00152 free(ha); 00153 return path; 00154 } 00155 ha->netaddr.s_addr &= ha->netmask.s_addr; 00156 if (!strncasecmp(sense, "p", 1)) { 00157 ha->sense = AST_SENSE_ALLOW; 00158 } else { 00159 ha->sense = AST_SENSE_DENY; 00160 } 00161 ha->next = NULL; 00162 if (prev) 00163 prev->next = ha; 00164 else 00165 ret = ha; 00166 } 00167 ast_log(LOG_DEBUG, "%s/%s appended to acl for peer\n",stuff, nm); 00168 return ret; 00169 }

int ast_apply_ha struct ast_ha ha,
struct sockaddr_in *  sin
 

Definition at line 171 of file acl.c.

References ast_log(), AST_SENSE_ALLOW, LOG_DEBUG, ast_ha::netaddr, ast_ha::netmask, ast_ha::next, and ast_ha::sense.

00172 { 00173 /* Start optimistic */ 00174 int res = AST_SENSE_ALLOW; 00175 while(ha) { 00176 /* DEBUG */ 00177 ast_log(LOG_DEBUG, "##### Testing %s with %s\n",inet_ntoa(sin->sin_addr), inet_ntoa(ha->netaddr) ); 00178 /* For each rule, if this address and the netmask = the net address 00179 apply the current rule */ 00180 if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr)) 00181 res = ha->sense; 00182 ha = ha->next; 00183 } 00184 return res; 00185 }

struct ast_ha* ast_duplicate_ha_list struct ast_ha original  ) 
 

Definition at line 92 of file acl.c.

00093 { 00094 struct ast_ha *start=original; 00095 struct ast_ha *ret = NULL; 00096 struct ast_ha *link,*prev=NULL; 00097 00098 while(start) { 00099 link = ast_duplicate_ha(start); /* Create copy of this object */ 00100 if (prev) 00101 prev->next = link; /* Link previous to this object */ 00102 00103 if (!ret) 00104 ret = link; /* Save starting point */ 00105 00106 start = start->next; /* Go to next object */ 00107 prev = link; /* Save pointer to this object */ 00108 } 00109 return (ret); /* Return start of list */ 00110 }

void ast_free_ha struct ast_ha ha  ) 
 

Definition at line 58 of file acl.c.

References free, and ast_ha::next.

00059 { 00060 struct ast_ha *hal; 00061 while(ha) { 00062 hal = ha; 00063 ha = ha->next; 00064 free(hal); 00065 } 00066 }

int ast_get_ip struct sockaddr_in *  sin,
char *  value
 

Definition at line 187 of file acl.c.

References ast_gethostbyname(), ast_log(), and LOG_WARNING.

00188 { 00189 struct hostent *hp; 00190 struct ast_hostent ahp; 00191 hp = ast_gethostbyname(value, &ahp); 00192 if (hp) { 00193 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 00194 } else { 00195 ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value); 00196 return -1; 00197 } 00198 return 0; 00199 }

int ast_lookup_iface char *  iface,
struct in_addr *  address
 

Definition at line 202 of file acl.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_ouraddrfor().

00202 { 00203 int mysock, res = 0; 00204 struct my_ifreq ifreq; 00205 00206 memset(&ifreq, 0, sizeof(ifreq)); 00207 strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1); 00208 00209 mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP); 00210 res = ioctl(mysock,SIOCGIFADDR,&ifreq); 00211 00212 close(mysock); 00213 if (res < 0) { 00214 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno)); 00215 memcpy((char *)address,(char *)&__ourip,sizeof(__ourip)); 00216 return -1; 00217 } else { 00218 memcpy((char *)address,(char *)&ifreq.ifru_addr.sin_addr,sizeof(ifreq.ifru_addr.sin_addr)); 00219 return 0; 00220 } 00221 }

int ast_ouraddrfor struct in_addr *  them,
struct in_addr *  us
 

Definition at line 223 of file acl.c.

References ast_log(), ast_lookup_iface(), ast_mutex_lock, ast_mutex_unlock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and s.

00224 { 00225 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) 00226 struct sockaddr_in *sin; 00227 struct sockaddr *sa; 00228 struct { 00229 struct rt_msghdr m_rtm; 00230 char m_space[512]; 00231 } m_rtmsg; 00232 char *cp, *p = ast_strdupa(inet_ntoa(*them)); 00233 int i, l, s, seq, flags; 00234 pid_t pid = getpid(); 00235 static int routeseq; /* Protected by "routeseq_lock" mutex */ 00236 00237 memset(us, 0, sizeof(struct in_addr)); 00238 00239 memset(&m_rtmsg, 0, sizeof(m_rtmsg)); 00240 m_rtmsg.m_rtm.rtm_type = RTM_GET; 00241 m_rtmsg.m_rtm.rtm_flags = RTF_UP | RTF_HOST; 00242 m_rtmsg.m_rtm.rtm_version = RTM_VERSION; 00243 ast_mutex_lock(&routeseq_lock); 00244 seq = ++routeseq; 00245 ast_mutex_unlock(&routeseq_lock); 00246 m_rtmsg.m_rtm.rtm_seq = seq; 00247 m_rtmsg.m_rtm.rtm_addrs = RTA_IFA | RTA_DST; 00248 m_rtmsg.m_rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in); 00249 sin = (struct sockaddr_in *)m_rtmsg.m_space; 00250 sin->sin_family = AF_INET; 00251 sin->sin_len = sizeof(struct sockaddr_in); 00252 sin->sin_addr = *them; 00253 00254 if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) { 00255 ast_log(LOG_ERROR, "Error opening routing socket\n"); 00256 return -1; 00257 } 00258 flags = fcntl(s, F_GETFL); 00259 fcntl(s, F_SETFL, flags | O_NONBLOCK); 00260 if (write(s, (char *)&m_rtmsg, m_rtmsg.m_rtm.rtm_msglen) < 0) { 00261 ast_log(LOG_ERROR, "Error writing to routing socket: %s\n", strerror(errno)); 00262 close(s); 00263 return -1; 00264 } 00265 do { 00266 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); 00267 } while (l > 0 && (m_rtmsg.m_rtm.rtm_seq != 1 || m_rtmsg.m_rtm.rtm_pid != pid)); 00268 if (l < 0) { 00269 if (errno != EAGAIN) 00270 ast_log(LOG_ERROR, "Error reading from routing socket\n"); 00271 close(s); 00272 return -1; 00273 } 00274 close(s); 00275 00276 if (m_rtmsg.m_rtm.rtm_version != RTM_VERSION) { 00277 ast_log(LOG_ERROR, "Unsupported route socket protocol version\n"); 00278 return -1; 00279 } 00280 00281 if (m_rtmsg.m_rtm.rtm_msglen != l) 00282 ast_log(LOG_WARNING, "Message length mismatch, in packet %d, returned %d\n", 00283 m_rtmsg.m_rtm.rtm_msglen, l); 00284 00285 if (m_rtmsg.m_rtm.rtm_errno) { 00286 ast_log(LOG_ERROR, "RTM_GET got %s (%d)\n", 00287 strerror(m_rtmsg.m_rtm.rtm_errno), m_rtmsg.m_rtm.rtm_errno); 00288 return -1; 00289 } 00290 00291 cp = (char *)m_rtmsg.m_space; 00292 if (m_rtmsg.m_rtm.rtm_addrs) 00293 for (i = 1; i; i <<= 1) 00294 if (m_rtmsg.m_rtm.rtm_addrs & i) { 00295 sa = (struct sockaddr *)cp; 00296 if (i == RTA_IFA && sa->sa_family == AF_INET) { 00297 sin = (struct sockaddr_in *)sa; 00298 *us = sin->sin_addr; 00299 ast_log(LOG_DEBUG, "Found route to %s, output from our address %s.\n", p, inet_ntoa(*us)); 00300 return 0; 00301 } 00302 cp += sa->sa_len > 0 ? 00303 (1 + ((sa->sa_len - 1) | (sizeof(long) - 1))) : 00304 sizeof(long); 00305 } 00306 00307 ast_log(LOG_DEBUG, "No route found for address %s!\n", p); 00308 return -1; 00309 #else 00310 FILE *PROC; 00311 unsigned int remote_ip; 00312 int res = 1; 00313 char line[256]; 00314 remote_ip = them->s_addr; 00315 00316 PROC = fopen("/proc/net/route","r"); 00317 if (!PROC) { 00318 bzero(us,sizeof(struct in_addr)); 00319 return -1; 00320 } 00321 /* First line contains headers */ 00322 fgets(line,sizeof(line),PROC); 00323 00324 while (!feof(PROC)) { 00325 char iface[256]; 00326 unsigned int dest, gateway, mask; 00327 int i,fieldnum; 00328 char *fields[40]; 00329 00330 fgets(line,sizeof(line),PROC); 00331 00332 fieldnum = 0; 00333 for (i=0;i<sizeof(line);i++) { 00334 char *offset; 00335 00336 fields[fieldnum++] = line + i; 00337 offset = strchr(line + i,'\t'); 00338 if (offset == NULL) { 00339 /* Exit loop */ 00340 break; 00341 } else if (fieldnum >= 9) { 00342 /* Short-circuit: can't break at 8, since the end of field 7 is figured when fieldnum=8 */ 00343 break; 00344 } else { 00345 *offset = '\0'; 00346 i = offset - line; 00347 } 00348 } 00349 if (fieldnum >= 8) { 00350 00351 sscanf(fields[0],"%s",iface); 00352 sscanf(fields[1],"%x",&dest); 00353 sscanf(fields[2],"%x",&gateway); 00354 sscanf(fields[7],"%x",&mask); 00355 #if 0 00356 printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask); 00357 #endif 00358 /* Looks simple, but here is the magic */ 00359 if (((remote_ip & mask) ^ dest) == 0) { 00360 res = ast_lookup_iface(iface,us); 00361 break; 00362 } 00363 } 00364 } 00365 fclose(PROC); 00366 if (res == 1) { 00367 ast_log(LOG_WARNING, "Yikes! No default route?!!\n"); 00368 bzero(us,sizeof(struct in_addr)); 00369 return -2; 00370 } else if (res) { 00371 /* We've already warned in subroutine */ 00372 return -1; 00373 } 00374 return 0; 00375 #endif 00376 }


Generated on Sat Jun 12 16:41:00 2004 for Asterisk by doxygen 1.3.7