| 849 | #define MAX_IFS 32 |
| 850 | |
| 851 | static int |
| 852 | get_ether_addr(in_addr_t ipaddr, struct ether_addr *hwaddr) |
| 853 | { |
| 854 | struct ifreq *ifr, *ifend, *ifp; |
| 855 | in_addr_t ina, mask; |
| 856 | struct sockaddr_dl *dla; |
| 857 | struct ifreq ifreq; |
| 858 | struct ifconf ifc; |
| 859 | struct ifreq ifs[MAX_IFS]; |
| 860 | int sock; |
| 861 | int retval = 0; |
| 862 | |
| 863 | sock = socket(AF_INET, SOCK_DGRAM, 0); |
| 864 | if (sock < 0) |
| 865 | xo_err(1, "socket"); |
| 866 | |
| 867 | ifc.ifc_len = sizeof(ifs); |
| 868 | ifc.ifc_req = ifs; |
| 869 | if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { |
| 870 | xo_warnx("ioctl(SIOCGIFCONF)"); |
| 871 | goto done; |
| 872 | } |
| 873 | |
| 874 | #define NEXTIFR(i) \ |
| 875 | ((struct ifreq *)((char *)&(i)->ifr_addr \ |
| 876 | + MAX((i)->ifr_addr.sa_len, sizeof((i)->ifr_addr))) ) |
| 877 | |
| 878 | /* |
| 879 | * Scan through looking for an interface with an Internet |
| 880 | * address on the same subnet as `ipaddr'. |
| 881 | */ |
| 882 | ifend = (struct ifreq *)(ifc.ifc_buf + ifc.ifc_len); |
| 883 | for (ifr = ifc.ifc_req; ifr < ifend; ifr = NEXTIFR(ifr) ) { |
| 884 | if (ifr->ifr_addr.sa_family != AF_INET) |
| 885 | continue; |
| 886 | strncpy(ifreq.ifr_name, ifr->ifr_name, |
| 887 | sizeof(ifreq.ifr_name)); |
| 888 | ifreq.ifr_addr = ifr->ifr_addr; |
| 889 | /* |
| 890 | * Check that the interface is up, |
| 891 | * and not point-to-point or loopback. |
| 892 | */ |
| 893 | if (ioctl(sock, SIOCGIFFLAGS, &ifreq) < 0) |
| 894 | continue; |
| 895 | if ((ifreq.ifr_flags & |
| 896 | (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT| |
| 897 | IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP|IFF_BROADCAST)) |
| 898 | continue; |
| 899 | /* Get its netmask and check that it's on the right subnet. */ |
| 900 | if (ioctl(sock, SIOCGIFNETMASK, &ifreq) < 0) |
| 901 | continue; |
| 902 | mask = ((struct sockaddr_in *) |
| 903 | &ifreq.ifr_addr)->sin_addr.s_addr; |
| 904 | ina = ((struct sockaddr_in *) |
| 905 | &ifr->ifr_addr)->sin_addr.s_addr; |
| 906 | if ((ipaddr & mask) == (ina & mask)) |
| 907 | break; /* ok, we got it! */ |
| 908 | } |