o Made some code changes to intf.c (the patch below). This does the following: o Preserve the alias qualifier from interface name in more cases (e.g. don't blow away :2 from eth0:2 when it may still be needed. o Set the SO_BROADCAST flag on the interface list descriptor so that broadcast/network IPs can be investigated. o Update _match_intf_src so that it checks interface aliases for the given source address rather than only the main interface address. --- src/intf.c 2005-02-10 17:57:35.000000000 +0100 +++ src/intf.c.oden 2005-12-10 20:16:15.000000000 +0100 @@ -119,12 +119,16 @@ intf_open(void) { intf_t *intf; + int one = 1; if ((intf = calloc(1, sizeof(*intf))) != NULL) { intf->fd = intf->fd6 = -1; if ((intf->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (intf_close(intf)); + + setsockopt(intf->fd, SOL_SOCKET, SO_BROADCAST, + (const char *) &one, sizeof(one)); #ifdef SIOCGIFNETMASK_IN6 if ((intf->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { # ifdef EPROTONOSUPPORT @@ -472,6 +476,7 @@ _intf_get_aliases(intf_t *intf, struct intf_entry *entry) { struct ifreq *ifr, *lifr; + struct ifreq tmpifr; struct addr *ap, *lap; char *p; @@ -492,9 +497,12 @@ if ((p = strchr(ifr->ifr_name, ':')) != NULL) *p = '\0'; - if (strcmp(ifr->ifr_name, entry->intf_name) != 0) + if (strcmp(ifr->ifr_name, entry->intf_name) != 0) { + if (p) *p = ':'; continue; + } + if (p) *p = ':'; /* Fix the name back up */ if (addr_ston(&ifr->ifr_addr, ap) < 0) continue; @@ -506,6 +514,10 @@ if (ap->addr_ip == entry->intf_addr.addr_ip || ap->addr_ip == entry->intf_dst_addr.addr_ip) continue; + strlcpy(tmpifr.ifr_name, ifr->ifr_name, + sizeof(tmpifr.ifr_name)); + if (ioctl(intf->fd, SIOCGIFNETMASK, &tmpifr) == 0) + addr_stob(&tmpifr.ifr_addr, &ap->addr_bits); } #ifdef SIOCGIFNETMASK_IN6 else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) { @@ -547,10 +559,22 @@ static int _match_intf_src(const struct intf_entry *entry, void *arg) { + int matched = 0; + int cnt; struct intf_entry *save = (struct intf_entry *)arg; if (entry->intf_addr.addr_type == ADDR_TYPE_IP && - entry->intf_addr.addr_ip == save->intf_addr.addr_ip) { + entry->intf_addr.addr_ip == save->intf_addr.addr_ip) + matched = 1; + + for (cnt = 0; !matched && cnt < (int) entry->intf_alias_num; cnt++) { + if (entry->intf_alias_addrs[cnt].addr_type != ADDR_TYPE_IP) + continue; + if (entry->intf_alias_addrs[cnt].addr_ip == save->intf_addr.addr_ip) + matched = 1; + } + + if (matched) { /* XXX - truncated result if entry is too small. */ if (save->intf_len < entry->intf_len) memcpy(save, entry, save->intf_len); @@ -678,14 +702,18 @@ if ((p = strchr(ifr->ifr_name, ':')) != NULL) *p = '\0'; - if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) + if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) { + if (p) *p = ':'; continue; + } memset(ebuf, 0, sizeof(ebuf)); strlcpy(entry->intf_name, ifr->ifr_name, sizeof(entry->intf_name)); entry->intf_len = sizeof(ebuf); + /* Repair the alias name back up. */ + if (p) *p = ':'; if (_intf_get_noalias(intf, entry) < 0) return (-1); if (_intf_get_aliases(intf, entry) < 0)