#include <stdio.h>#include <stdlib.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 <asterisk/lock.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>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_ha * | ast_duplicate_ha_list (struct ast_ha *original) |
| ast_ha * | ast_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) |
|
||||||||||||||||
|
Definition at line 110 of file acl.c. References ast_log(), AST_SENSE_ALLOW, AST_SENSE_DENY, free, LOG_DEBUG, LOG_WARNING, malloc, ast_ha::netaddr, ast_ha::netmask, ast_ha::next, and ast_ha::sense.
00111 {
00112 struct ast_ha *ha = malloc(sizeof(struct ast_ha));
00113 char *nm="255.255.255.255";
00114 char tmp[256] = "";
00115 struct ast_ha *prev = NULL;
00116 struct ast_ha *ret;
00117 int x,z;
00118 unsigned int y;
00119 ret = path;
00120 while(path) {
00121 prev = path;
00122 path = path->next;
00123 }
00124 if (ha) {
00125 strncpy(tmp, stuff, sizeof(tmp) - 1);
00126 nm = strchr(tmp, '/');
00127 if (!nm)
00128 nm = "255.255.255.255";
00129 else {
00130 *nm = '\0';
00131 nm++;
00132 }
00133 if (!strchr(nm, '.')) {
00134 if ((sscanf(nm, "%i", &x) == 1) && (x >= 0) && (x <= 32)) {
00135 y = 0;
00136 for (z=0;z<x;z++) {
00137 y >>= 1;
00138 y |= 0x80000000;
00139 }
00140 ha->netmask.s_addr = htonl(y);
00141 }
00142 } else if (!inet_aton(nm, &ha->netmask)) {
00143 ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
00144 free(ha);
00145 return path;
00146 }
00147 if (!inet_aton(tmp, &ha->netaddr)) {
00148 ast_log(LOG_WARNING, "%s not a valid IP\n", tmp);
00149 free(ha);
00150 return path;
00151 }
00152 ha->netaddr.s_addr &= ha->netmask.s_addr;
00153 if (!strncasecmp(sense, "p", 1)) {
00154 ha->sense = AST_SENSE_ALLOW;
00155 } else {
00156 ha->sense = AST_SENSE_DENY;
00157 }
00158 ha->next = NULL;
00159 if (prev)
00160 prev->next = ha;
00161 else
00162 ret = ha;
00163 }
00164 ast_log(LOG_DEBUG, "%s/%s appended to acl for peer\n",stuff, nm);
00165 return ret;
00166 }
|
|
||||||||||||
|
Definition at line 168 of file acl.c. References ast_inet_ntoa(), ast_log(), AST_SENSE_ALLOW, LOG_DEBUG, ast_ha::netaddr, ast_ha::netmask, ast_ha::next, and ast_ha::sense.
00169 {
00170 /* Start optimistic */
00171 int res = AST_SENSE_ALLOW;
00172 while(ha) {
00173 char iabuf[INET_ADDRSTRLEN];
00174 char iabuf2[INET_ADDRSTRLEN];
00175 /* DEBUG */
00176 ast_log(LOG_DEBUG,
00177 "##### Testing %s with %s\n",
00178 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr),
00179 ast_inet_ntoa(iabuf2, sizeof(iabuf2), ha->netaddr));
00180 /* For each rule, if this address and the netmask = the net address
00181 apply the current rule */
00182 if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr))
00183 res = ha->sense;
00184 ha = ha->next;
00185 }
00186 return res;
00187 }
|
|
|
Definition at line 90 of file acl.c. References ast_ha::next.
00091 {
00092 struct ast_ha *start=original;
00093 struct ast_ha *ret = NULL;
00094 struct ast_ha *link,*prev=NULL;
00095
00096 while(start) {
00097 link = ast_duplicate_ha(start); /* Create copy of this object */
00098 if (prev)
00099 prev->next = link; /* Link previous to this object */
00100
00101 if (!ret)
00102 ret = link; /* Save starting point */
00103
00104 start = start->next; /* Go to next object */
00105 prev = link; /* Save pointer to this object */
00106 }
00107 return (ret); /* Return start of list */
00108 }
|
|
|
Definition at line 58 of file acl.c. References free, and ast_ha::next.
|
|
||||||||||||
|
Definition at line 189 of file acl.c. References ast_gethostbyname(), ast_log(), and LOG_WARNING.
00190 {
00191 struct hostent *hp;
00192 struct ast_hostent ahp;
00193 hp = ast_gethostbyname(value, &ahp);
00194 if (hp) {
00195 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
00196 } else {
00197 ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
00198 return -1;
00199 }
00200 return 0;
00201 }
|
|
||||||||||||
|
Definition at line 204 of file acl.c. References ast_log(), my_ifreq::ifrn_name, my_ifreq::ifru_addr, and LOG_WARNING. Referenced by ast_ouraddrfor().
00204 {
00205 int mysock, res = 0;
00206 struct my_ifreq ifreq;
00207
00208 memset(&ifreq, 0, sizeof(ifreq));
00209 strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1);
00210
00211 mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
00212 res = ioctl(mysock,SIOCGIFADDR,&ifreq);
00213
00214 close(mysock);
00215 if (res < 0) {
00216 ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
00217 memcpy((char *)address,(char *)&__ourip,sizeof(__ourip));
00218 return -1;
00219 } else {
00220 memcpy((char *)address,(char *)&ifreq.ifru_addr.sin_addr,sizeof(ifreq.ifru_addr.sin_addr));
00221 return 0;
00222 }
00223 }
|
|
||||||||||||
|
Definition at line 225 of file acl.c. References ast_inet_ntoa(), ast_log(), ast_lookup_iface(), ast_mutex_lock, ast_mutex_unlock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and s.
00226 {
00227 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
00228 struct sockaddr_in *sin;
00229 struct sockaddr *sa;
00230 struct {
00231 struct rt_msghdr m_rtm;
00232 char m_space[512];
00233 } m_rtmsg;
00234 char iabuf[INET_ADDRSTRLEN];
00235 char *cp, *p;
00236 int i, l, s, seq, flags;
00237 pid_t pid = getpid();
00238 static int routeseq; /* Protected by "routeseq_lock" mutex */
00239
00240 p = ast_strdupa(ast_inet_ntoa(iabuf, sizeof(iabuf), *them));
00241 memset(us, 0, sizeof(struct in_addr));
00242
00243 memset(&m_rtmsg, 0, sizeof(m_rtmsg));
00244 m_rtmsg.m_rtm.rtm_type = RTM_GET;
00245 m_rtmsg.m_rtm.rtm_flags = RTF_UP | RTF_HOST;
00246 m_rtmsg.m_rtm.rtm_version = RTM_VERSION;
00247 ast_mutex_lock(&routeseq_lock);
00248 seq = ++routeseq;
00249 ast_mutex_unlock(&routeseq_lock);
00250 m_rtmsg.m_rtm.rtm_seq = seq;
00251 m_rtmsg.m_rtm.rtm_addrs = RTA_IFA | RTA_DST;
00252 m_rtmsg.m_rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
00253 sin = (struct sockaddr_in *)m_rtmsg.m_space;
00254 sin->sin_family = AF_INET;
00255 sin->sin_len = sizeof(struct sockaddr_in);
00256 sin->sin_addr = *them;
00257
00258 if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
00259 ast_log(LOG_ERROR, "Error opening routing socket\n");
00260 return -1;
00261 }
00262 flags = fcntl(s, F_GETFL);
00263 fcntl(s, F_SETFL, flags | O_NONBLOCK);
00264 if (write(s, (char *)&m_rtmsg, m_rtmsg.m_rtm.rtm_msglen) < 0) {
00265 ast_log(LOG_ERROR, "Error writing to routing socket: %s\n", strerror(errno));
00266 close(s);
00267 return -1;
00268 }
00269 do {
00270 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
00271 } while (l > 0 && (m_rtmsg.m_rtm.rtm_seq != 1 || m_rtmsg.m_rtm.rtm_pid != pid));
00272 if (l < 0) {
00273 if (errno != EAGAIN)
00274 ast_log(LOG_ERROR, "Error reading from routing socket\n");
00275 close(s);
00276 return -1;
00277 }
00278 close(s);
00279
00280 if (m_rtmsg.m_rtm.rtm_version != RTM_VERSION) {
00281 ast_log(LOG_ERROR, "Unsupported route socket protocol version\n");
00282 return -1;
00283 }
00284
00285 if (m_rtmsg.m_rtm.rtm_msglen != l)
00286 ast_log(LOG_WARNING, "Message length mismatch, in packet %d, returned %d\n",
00287 m_rtmsg.m_rtm.rtm_msglen, l);
00288
00289 if (m_rtmsg.m_rtm.rtm_errno) {
00290 ast_log(LOG_ERROR, "RTM_GET got %s (%d)\n",
00291 strerror(m_rtmsg.m_rtm.rtm_errno), m_rtmsg.m_rtm.rtm_errno);
00292 return -1;
00293 }
00294
00295 cp = (char *)m_rtmsg.m_space;
00296 if (m_rtmsg.m_rtm.rtm_addrs)
00297 for (i = 1; i; i <<= 1)
00298 if (m_rtmsg.m_rtm.rtm_addrs & i) {
00299 sa = (struct sockaddr *)cp;
00300 if (i == RTA_IFA && sa->sa_family == AF_INET) {
00301 sin = (struct sockaddr_in *)sa;
00302 *us = sin->sin_addr;
00303 ast_log(LOG_DEBUG, "Found route to %s, output from our address %s.\n", p, ast_inet_ntoa(iabuf, sizeof(iabuf), *us));
00304 return 0;
00305 }
00306 cp += sa->sa_len > 0 ?
00307 (1 + ((sa->sa_len - 1) | (sizeof(long) - 1))) :
00308 sizeof(long);
00309 }
00310
00311 ast_log(LOG_DEBUG, "No route found for address %s!\n", p);
00312 return -1;
00313 #else
00314 FILE *PROC;
00315 unsigned int remote_ip;
00316 int res = 1;
00317 char line[256];
00318 remote_ip = them->s_addr;
00319
00320 PROC = fopen("/proc/net/route","r");
00321 if (!PROC) {
00322 bzero(us,sizeof(struct in_addr));
00323 return -1;
00324 }
00325 /* First line contains headers */
00326 fgets(line,sizeof(line),PROC);
00327
00328 while (!feof(PROC)) {
00329 char iface[256];
00330 unsigned int dest, gateway, mask;
00331 int i,fieldnum;
00332 char *fields[40];
00333
00334 fgets(line,sizeof(line),PROC);
00335
00336 fieldnum = 0;
00337 for (i=0;i<sizeof(line);i++) {
00338 char *offset;
00339
00340 fields[fieldnum++] = line + i;
00341 offset = strchr(line + i,'\t');
00342 if (offset == NULL) {
00343 /* Exit loop */
00344 break;
00345 } else if (fieldnum >= 9) {
00346 /* Short-circuit: can't break at 8, since the end of field 7 is figured when fieldnum=8 */
00347 break;
00348 } else {
00349 *offset = '\0';
00350 i = offset - line;
00351 }
00352 }
00353 if (fieldnum >= 8) {
00354
00355 sscanf(fields[0],"%s",iface);
00356 sscanf(fields[1],"%x",&dest);
00357 sscanf(fields[2],"%x",&gateway);
00358 sscanf(fields[7],"%x",&mask);
00359 #if 0
00360 { char iabuf[INET_ADDRSTRLEN];
00361 printf("Addr: %s %08x Dest: %08x Mask: %08x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), *them), remote_ip, dest, mask); }
00362 #endif
00363 /* Looks simple, but here is the magic */
00364 if (((remote_ip & mask) ^ dest) == 0) {
00365 res = ast_lookup_iface(iface,us);
00366 break;
00367 }
00368 }
00369 }
00370 fclose(PROC);
00371 if (res == 1) {
00372 ast_log(LOG_WARNING, "Yikes! No default route?!!\n");
00373 bzero(us,sizeof(struct in_addr));
00374 return -2;
00375 } else if (res) {
00376 /* We've already warned in subroutine */
00377 return -1;
00378 }
00379 return 0;
00380 #endif
00381 }
|
1.2.15