Index: acl.c =================================================================== RCS file: /usr/cvsroot/asterisk/acl.c,v retrieving revision 1.27 diff -u -r1.27 acl.c --- acl.c 30 Jun 2004 16:56:51 -0000 1.27 +++ acl.c 7 Sep 2004 23:00:27 -0000 @@ -46,6 +46,14 @@ struct ast_ha *next; }; +struct ast_if_t { + char name[IFNAMSIZ+1]; + struct in_addr addr; + uint32_t mask; + short int flags; + int index; +}; + /* Default IP - if not otherwise set, don't breathe garbage */ static struct in_addr __ourip = { 0x00000000 }; @@ -222,6 +230,98 @@ } } +// SC +int ast_lookup_iface_2(struct ast_if_t *ife) +{ + struct ifreq lifr; + int fd; + + memset(&lifr, 0, sizeof(struct ifreq)); + ast_log(LOG_WARNING, "Fetching %s ...\n", ife->name); + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) + { + ast_log(LOG_WARNING, "socket() failed (%d-%s)\n", errno, strerror(errno)); + return -1; + } + + // flags + strcpy(lifr.ifr_name, ife->name); + if (ioctl(fd, SIOCGIFFLAGS, &lifr) < 0) + { + ast_log(LOG_WARNING, "ioctl() SIOCGIFFLAGS failed (%d-%s)\n", + errno, strerror(errno)); + close(fd); + return -1; + } + ife->flags = lifr.ifr_flags; + + // IP addr + strcpy(lifr.ifr_name, ife->name); + lifr.ifr_addr.sa_family = AF_INET; + if (ioctl(fd, SIOCGIFADDR, &lifr) < 0) + { + ast_log(LOG_WARNING, "ioctl() SIOCGIFADDR failed (%d-%s)\n", + errno, strerror(errno)); + close(fd); + return -1; + } + + ife->addr = ((struct sockaddr_in *)&lifr.ifr_addr)->sin_addr; + + // netmask addr + strcpy(lifr.ifr_name, ife->name); + if (ioctl(fd, SIOCGIFNETMASK, &lifr) < 0) + { + ast_log(LOG_WARNING, "ioctl() SIOCGIFNETMASK failed (%d-%s)\n", + errno, strerror(errno)); + close(fd); + return -1; + } + + ife->mask = *((uint32_t *)(&(((struct sockaddr_in *)&lifr.ifr_netmask)->sin_addr))); + + ast_log(LOG_WARNING,"%s: inet 0x%0u mask 0x%0u index %d flags 0x%0x \n", + ife->name, + ife->addr.s_addr, + ife->mask, + ife->index, + ife->flags + ); + + close(fd); + + return 0; +} + +// SC +int ast_get_if_list(struct ast_if_t *if_list, int *size) +{ + int n; + struct if_nameindex *list, *p; + + list = if_nameindex(); + if (!list || !size || !if_list) + return -1; + + for (n = 0, p = list; p->if_name && (n < *size); p++) + { + strcpy(if_list[n].name, p->if_name); + if_list[n].index = p->if_index; + if (ast_lookup_iface_2(&if_list[n]) == -1) + continue; + + // skip loopback + if (if_list[n].flags & IFF_LOOPBACK) + continue; + + n++; + } + + if_freenameindex(list); + *size = n; + return 0; +} + int ast_ouraddrfor(struct in_addr *them, struct in_addr *us) { #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) @@ -315,6 +415,7 @@ unsigned int remote_ip; int res = 1; char line[256]; + struct ast_if_t if_list[32]; remote_ip = them->s_addr; PROC = fopen("/proc/net/route","r"); @@ -362,8 +463,25 @@ #endif /* Looks simple, but here is the magic */ if (((remote_ip & mask) ^ dest) == 0) { - res = ast_lookup_iface(iface,us); - break; + int num = (int) (sizeof(if_list) / sizeof(struct ast_if_t)); + int i; + res = ast_lookup_iface(iface,us); + //SC: try to locate a logical interface + if (res == 0) + { + if (ast_get_if_list(if_list, &num)==0) { + for (i=0; i