arp.c (a0d6d0d0b9aba6d4c025b2f2807e7c4b4c4b2415) | arp.c (d80d73493767111b7569e831a93061014c682274) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1984, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Sun Microsystems, Inc. --- 65 unchanged lines hidden (view full) --- 74#include <netdb.h> 75#include <nlist.h> 76#include <paths.h> 77#include <stdio.h> 78#include <stdlib.h> 79#include <string.h> 80#include <strings.h> 81#include <unistd.h> | 1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1984, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Sun Microsystems, Inc. --- 65 unchanged lines hidden (view full) --- 74#include <netdb.h> 75#include <nlist.h> 76#include <paths.h> 77#include <stdio.h> 78#include <stdlib.h> 79#include <string.h> 80#include <strings.h> 81#include <unistd.h> |
82#include <ifaddrs.h> |
|
82#include <libxo/xo.h> 83 84typedef void (action_fn)(struct sockaddr_dl *sdl, struct sockaddr_in *s_in, 85 struct rt_msghdr *rtm); 86 87static int search(u_long addr, action_fn *action); 88static action_fn print_entry; 89static action_fn nuke_entry; --- 699 unchanged lines hidden (view full) --- 789 xo_warn("read from routing socket"); 790 return (rtm); 791} 792 793/* 794 * get_ether_addr - get the hardware address of an interface on the 795 * the same subnet as ipaddr. 796 */ | 83#include <libxo/xo.h> 84 85typedef void (action_fn)(struct sockaddr_dl *sdl, struct sockaddr_in *s_in, 86 struct rt_msghdr *rtm); 87 88static int search(u_long addr, action_fn *action); 89static action_fn print_entry; 90static action_fn nuke_entry; --- 699 unchanged lines hidden (view full) --- 790 xo_warn("read from routing socket"); 791 return (rtm); 792} 793 794/* 795 * get_ether_addr - get the hardware address of an interface on the 796 * the same subnet as ipaddr. 797 */ |
797#define MAX_IFS 32 798 | |
799static int 800get_ether_addr(in_addr_t ipaddr, struct ether_addr *hwaddr) 801{ | 798static int 799get_ether_addr(in_addr_t ipaddr, struct ether_addr *hwaddr) 800{ |
802 struct ifreq *ifr, *ifend, *ifp; | 801 struct ifaddrs *ifa, *ifd, *ifas = NULL; |
803 in_addr_t ina, mask; 804 struct sockaddr_dl *dla; | 802 in_addr_t ina, mask; 803 struct sockaddr_dl *dla; |
805 struct ifreq ifreq; 806 struct ifconf ifc; 807 struct ifreq ifs[MAX_IFS]; 808 int sock; | |
809 int retval = 0; 810 | 804 int retval = 0; 805 |
811 sock = socket(AF_INET, SOCK_DGRAM, 0); 812 if (sock < 0) 813 xo_err(1, "socket"); 814 815 ifc.ifc_len = sizeof(ifs); 816 ifc.ifc_req = ifs; 817 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { 818 xo_warnx("ioctl(SIOCGIFCONF)"); 819 goto done; 820 } 821 822#define NEXTIFR(i) \ 823 ((struct ifreq *)((char *)&(i)->ifr_addr \ 824 + MAX((i)->ifr_addr.sa_len, sizeof((i)->ifr_addr))) ) 825 | |
826 /* 827 * Scan through looking for an interface with an Internet 828 * address on the same subnet as `ipaddr'. 829 */ | 806 /* 807 * Scan through looking for an interface with an Internet 808 * address on the same subnet as `ipaddr'. 809 */ |
830 ifend = (struct ifreq *)(ifc.ifc_buf + ifc.ifc_len); 831 for (ifr = ifc.ifc_req; ifr < ifend; ifr = NEXTIFR(ifr) ) { 832 if (ifr->ifr_addr.sa_family != AF_INET) | 810 if (getifaddrs(&ifas) < 0) { 811 xo_warnx("getifaddrs"); 812 goto done; 813 } 814 815 for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) { 816 if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) |
833 continue; | 817 continue; |
834 strncpy(ifreq.ifr_name, ifr->ifr_name, 835 sizeof(ifreq.ifr_name)); 836 ifreq.ifr_addr = ifr->ifr_addr; | 818 if (ifa->ifa_addr->sa_family != AF_INET) 819 continue; |
837 /* 838 * Check that the interface is up, 839 * and not point-to-point or loopback. 840 */ | 820 /* 821 * Check that the interface is up, 822 * and not point-to-point or loopback. 823 */ |
841 if (ioctl(sock, SIOCGIFFLAGS, &ifreq) < 0) 842 continue; 843 if ((ifreq.ifr_flags & | 824 if ((ifa->ifa_flags & |
844 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT| 845 IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP|IFF_BROADCAST)) 846 continue; 847 /* Get its netmask and check that it's on the right subnet. */ | 825 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT| 826 IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP|IFF_BROADCAST)) 827 continue; 828 /* Get its netmask and check that it's on the right subnet. */ |
848 if (ioctl(sock, SIOCGIFNETMASK, &ifreq) < 0) 849 continue; | |
850 mask = ((struct sockaddr_in *) | 829 mask = ((struct sockaddr_in *) |
851 &ifreq.ifr_addr)->sin_addr.s_addr; | 830 ifa->ifa_netmask)->sin_addr.s_addr; |
852 ina = ((struct sockaddr_in *) | 831 ina = ((struct sockaddr_in *) |
853 &ifr->ifr_addr)->sin_addr.s_addr; | 832 ifa->ifa_addr)->sin_addr.s_addr; |
854 if ((ipaddr & mask) == (ina & mask)) 855 break; /* ok, we got it! */ 856 } | 833 if ((ipaddr & mask) == (ina & mask)) 834 break; /* ok, we got it! */ 835 } |
857 858 if (ifr >= ifend) | 836 if (ifa == NULL) |
859 goto done; 860 861 /* 862 * Now scan through again looking for a link-level address 863 * for this interface. 864 */ | 837 goto done; 838 839 /* 840 * Now scan through again looking for a link-level address 841 * for this interface. 842 */ |
865 ifp = ifr; 866 for (ifr = ifc.ifc_req; ifr < ifend; ifr = NEXTIFR(ifr)) 867 if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0 && 868 ifr->ifr_addr.sa_family == AF_LINK) | 843 for (ifd = ifas; ifd != NULL; ifd = ifd->ifa_next) { 844 if (ifd->ifa_addr == NULL) 845 continue; 846 if (strcmp(ifa->ifa_name, ifd->ifa_name) == 0 && 847 ifd->ifa_addr->sa_family == AF_LINK) |
869 break; | 848 break; |
870 if (ifr >= ifend) | 849 } 850 if (ifd == NULL) |
871 goto done; 872 /* 873 * Found the link-level address - copy it out 874 */ | 851 goto done; 852 /* 853 * Found the link-level address - copy it out 854 */ |
875 dla = (struct sockaddr_dl *) &ifr->ifr_addr; | 855 dla = (struct sockaddr_dl *)ifd->ifa_addr; |
876 memcpy(hwaddr, LLADDR(dla), dla->sdl_alen); | 856 memcpy(hwaddr, LLADDR(dla), dla->sdl_alen); |
877 printf("using interface %s for proxy with address %s\n", ifp->ifr_name, | 857 printf("using interface %s for proxy with address %s\n", ifa->ifa_name, |
878 ether_ntoa(hwaddr)); 879 retval = dla->sdl_alen; 880done: | 858 ether_ntoa(hwaddr)); 859 retval = dla->sdl_alen; 860done: |
881 close(sock); | 861 if (ifas != NULL) 862 freeifaddrs(ifas); |
882 return (retval); 883} | 863 return (retval); 864} |