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}