121993Sdist /*
261540Sbostic * Copyright (c) 1983, 1993
361540Sbostic * The Regents of the University of California. All rights reserved.
433489Sbostic *
542712Sbostic * %sccs.include.redist.c%
621993Sdist */
721993Sdist
89015Ssam #ifndef lint
9*69037Sbostic static char sccsid[] = "@(#)if.c 8.2 (Berkeley) 04/28/95";
1033489Sbostic #endif /* not lint */
119015Ssam
129015Ssam /*
139015Ssam * Routing Table Management Daemon
149015Ssam */
1510245Ssam #include "defs.h"
169015Ssam
179015Ssam extern struct interface *ifnet;
189015Ssam
199015Ssam /*
2017569Skarels * Find the interface with address addr.
219015Ssam */
229015Ssam struct interface *
if_ifwithaddr(addr)239015Ssam if_ifwithaddr(addr)
249015Ssam struct sockaddr *addr;
259015Ssam {
269015Ssam register struct interface *ifp;
279015Ssam
289015Ssam #define same(a1, a2) \
29*69037Sbostic (memcmp((a1)->sa_data, (a2)->sa_data, 14) == 0)
309015Ssam for (ifp = ifnet; ifp; ifp = ifp->int_next) {
319015Ssam if (ifp->int_flags & IFF_REMOTE)
329015Ssam continue;
339015Ssam if (ifp->int_addr.sa_family != addr->sa_family)
349015Ssam continue;
359015Ssam if (same(&ifp->int_addr, addr))
369015Ssam break;
379015Ssam if ((ifp->int_flags & IFF_BROADCAST) &&
389015Ssam same(&ifp->int_broadaddr, addr))
399015Ssam break;
409015Ssam }
419015Ssam return (ifp);
429015Ssam }
439015Ssam
449015Ssam /*
4517569Skarels * Find the point-to-point interface with destination address addr.
4617569Skarels */
4717569Skarels struct interface *
if_ifwithdstaddr(addr)4817569Skarels if_ifwithdstaddr(addr)
4917569Skarels struct sockaddr *addr;
5017569Skarels {
5117569Skarels register struct interface *ifp;
5217569Skarels
5317569Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) {
5417569Skarels if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
5517569Skarels continue;
5617569Skarels if (same(&ifp->int_dstaddr, addr))
5717569Skarels break;
5817569Skarels }
5917569Skarels return (ifp);
6017569Skarels }
6117569Skarels
6217569Skarels /*
639015Ssam * Find the interface on the network
649015Ssam * of the specified address.
659015Ssam */
669015Ssam struct interface *
if_ifwithnet(addr)679015Ssam if_ifwithnet(addr)
689015Ssam register struct sockaddr *addr;
699015Ssam {
709015Ssam register struct interface *ifp;
719015Ssam register int af = addr->sa_family;
729015Ssam register int (*netmatch)();
739015Ssam
7426340Skarels if (af >= af_max)
759015Ssam return (0);
769015Ssam netmatch = afswitch[af].af_netmatch;
779015Ssam for (ifp = ifnet; ifp; ifp = ifp->int_next) {
789015Ssam if (ifp->int_flags & IFF_REMOTE)
799015Ssam continue;
809015Ssam if (af != ifp->int_addr.sa_family)
819015Ssam continue;
829015Ssam if ((*netmatch)(addr, &ifp->int_addr))
839015Ssam break;
849015Ssam }
859015Ssam return (ifp);
869015Ssam }
879015Ssam
889015Ssam /*
899015Ssam * Find an interface from which the specified address
909015Ssam * should have come from. Used for figuring out which
919015Ssam * interface a packet came in on -- for tracing.
929015Ssam */
939015Ssam struct interface *
if_iflookup(addr)949015Ssam if_iflookup(addr)
959015Ssam struct sockaddr *addr;
969015Ssam {
979015Ssam register struct interface *ifp, *maybe;
989015Ssam register int af = addr->sa_family;
999015Ssam register int (*netmatch)();
1009015Ssam
10126340Skarels if (af >= af_max)
1029015Ssam return (0);
1039015Ssam maybe = 0;
1049015Ssam netmatch = afswitch[af].af_netmatch;
1059015Ssam for (ifp = ifnet; ifp; ifp = ifp->int_next) {
1069015Ssam if (ifp->int_addr.sa_family != af)
1079015Ssam continue;
1089015Ssam if (same(&ifp->int_addr, addr))
1099015Ssam break;
1109015Ssam if ((ifp->int_flags & IFF_BROADCAST) &&
1119015Ssam same(&ifp->int_broadaddr, addr))
1129015Ssam break;
11327231Skarels if ((ifp->int_flags & IFF_POINTOPOINT) &&
11427231Skarels same(&ifp->int_dstaddr, addr))
11527231Skarels break;
1169015Ssam if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr))
1179015Ssam maybe = ifp;
1189015Ssam }
1199015Ssam if (ifp == 0)
1209015Ssam ifp = maybe;
1219015Ssam return (ifp);
1229015Ssam }
123