135591Sbostic /*
2*61474Sbostic * Copyright (c) 1983, 1993
3*61474Sbostic * The Regents of the University of California. All rights reserved.
435591Sbostic *
542698Sbostic * %sccs.include.redist.c%
635591Sbostic *
735591Sbostic * static char sccsid[] = "@(#)if.c 5.1 (Berkeley) 6/4/85"; (routed/if.c)
835591Sbostic */
935591Sbostic
1035591Sbostic #ifndef lint
11*61474Sbostic static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 06/05/93";
1235591Sbostic #endif /* not lint */
1335591Sbostic
1435591Sbostic /*
1535591Sbostic * Routing Table Management Daemon
1635591Sbostic */
1735591Sbostic #include "defs.h"
1835591Sbostic
1935591Sbostic extern struct interface *ifnet;
2035591Sbostic
2135591Sbostic /*
2235591Sbostic * Find the interface with address addr.
2335591Sbostic */
2435591Sbostic struct interface *
if_ifwithaddr(addr)2535591Sbostic if_ifwithaddr(addr)
2635591Sbostic struct sockaddr *addr;
2735591Sbostic {
2835591Sbostic register struct interface *ifp;
2935591Sbostic
3035591Sbostic #define same(a1, a2) \
3135591Sbostic (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
3235591Sbostic for (ifp = ifnet; ifp; ifp = ifp->int_next) {
3335591Sbostic if (ifp->int_flags & IFF_REMOTE)
3435591Sbostic continue;
3535591Sbostic if (ifp->int_addr.sa_family != addr->sa_family)
3635591Sbostic continue;
3735591Sbostic if (same(&ifp->int_addr, addr))
3835591Sbostic break;
3935591Sbostic if ((ifp->int_flags & IFF_BROADCAST) &&
4035591Sbostic same(&ifp->int_broadaddr, addr))
4135591Sbostic break;
4235591Sbostic }
4335591Sbostic return (ifp);
4435591Sbostic }
4535591Sbostic
4635591Sbostic /*
4735591Sbostic * Find the point-to-point interface with destination address addr.
4835591Sbostic */
4935591Sbostic struct interface *
if_ifwithdstaddr(addr)5035591Sbostic if_ifwithdstaddr(addr)
5135591Sbostic struct sockaddr *addr;
5235591Sbostic {
5335591Sbostic register struct interface *ifp;
5435591Sbostic
5535591Sbostic for (ifp = ifnet; ifp; ifp = ifp->int_next) {
5635591Sbostic if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
5735591Sbostic continue;
5835591Sbostic if (same(&ifp->int_dstaddr, addr))
5935591Sbostic break;
6035591Sbostic }
6135591Sbostic return (ifp);
6235591Sbostic }
6335591Sbostic
6435591Sbostic /*
6535591Sbostic * Find the interface on the network
6635591Sbostic * of the specified address.
6735591Sbostic */
6835591Sbostic struct interface *
if_ifwithnet(addr)6935591Sbostic if_ifwithnet(addr)
7035591Sbostic register struct sockaddr *addr;
7135591Sbostic {
7235591Sbostic register struct interface *ifp;
7335591Sbostic register int af = addr->sa_family;
7435591Sbostic register int (*netmatch)();
7535591Sbostic
7635591Sbostic if (af >= AF_MAX)
7735591Sbostic return (0);
7835591Sbostic netmatch = afswitch[af].af_netmatch;
7935591Sbostic for (ifp = ifnet; ifp; ifp = ifp->int_next) {
8035591Sbostic if (ifp->int_flags & IFF_REMOTE)
8135591Sbostic continue;
8235591Sbostic if (af != ifp->int_addr.sa_family)
8335591Sbostic continue;
8435591Sbostic if ((*netmatch)(addr, &ifp->int_addr))
8535591Sbostic break;
8635591Sbostic }
8735591Sbostic return (ifp);
8835591Sbostic }
8935591Sbostic
9035591Sbostic /*
9135591Sbostic * Find an interface from which the specified address
9235591Sbostic * should have come from. Used for figuring out which
9335591Sbostic * interface a packet came in on -- for tracing.
9435591Sbostic */
9535591Sbostic struct interface *
if_iflookup(addr)9635591Sbostic if_iflookup(addr)
9735591Sbostic struct sockaddr *addr;
9835591Sbostic {
9935591Sbostic register struct interface *ifp, *maybe;
10035591Sbostic register int af = addr->sa_family;
10135591Sbostic register int (*netmatch)();
10235591Sbostic
10335591Sbostic if (af >= AF_MAX)
10435591Sbostic return (0);
10535591Sbostic maybe = 0;
10635591Sbostic netmatch = afswitch[af].af_netmatch;
10735591Sbostic for (ifp = ifnet; ifp; ifp = ifp->int_next) {
10835591Sbostic if (ifp->int_addr.sa_family != af)
10935591Sbostic continue;
11035591Sbostic if (same(&ifp->int_addr, addr))
11135591Sbostic break;
11235591Sbostic if ((ifp->int_flags & IFF_BROADCAST) &&
11335591Sbostic same(&ifp->int_broadaddr, addr))
11435591Sbostic break;
11535591Sbostic if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr))
11635591Sbostic maybe = ifp;
11735591Sbostic }
11835591Sbostic if (ifp == 0)
11935591Sbostic ifp = maybe;
12035591Sbostic return (ifp);
12135591Sbostic }
122