1 /* $NetBSD: if.c,v 1.7 1995/03/18 15:00:28 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; 39 #else 40 static char rcsid[] = "$NetBSD: if.c,v 1.7 1995/03/18 15:00:28 cgd Exp $"; 41 #endif 42 #endif /* not lint */ 43 44 /* 45 * Routing Table Management Daemon 46 */ 47 #include "defs.h" 48 49 extern struct interface *ifnet; 50 51 /* 52 * Find the interface with address addr. 53 */ 54 struct interface * 55 if_ifwithaddr(addr) 56 struct sockaddr *addr; 57 { 58 register struct interface *ifp; 59 60 #define same(a1, a2) \ 61 (memcmp((a1)->sa_data, (a2)->sa_data, 14) == 0) 62 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 63 if (ifp->int_flags & IFF_REMOTE) 64 continue; 65 if (ifp->int_addr.sa_family != addr->sa_family) 66 continue; 67 if (same(&ifp->int_addr, addr)) 68 break; 69 if ((ifp->int_flags & IFF_BROADCAST) && 70 same(&ifp->int_broadaddr, addr)) 71 break; 72 } 73 return (ifp); 74 } 75 76 /* 77 * Find the point-to-point interface with destination address addr. 78 */ 79 struct interface * 80 if_ifwithdstaddr(addr) 81 struct sockaddr *addr; 82 { 83 register struct interface *ifp; 84 85 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 86 if ((ifp->int_flags & IFF_POINTOPOINT) == 0) 87 continue; 88 if (same(&ifp->int_dstaddr, addr)) 89 break; 90 } 91 return (ifp); 92 } 93 94 /* 95 * Find the interface on the network 96 * of the specified address. 97 */ 98 struct interface * 99 if_ifwithnet(addr) 100 register struct sockaddr *addr; 101 { 102 register struct interface *ifp; 103 register int af = addr->sa_family; 104 register int (*netmatch)(); 105 106 if (af >= af_max) 107 return (0); 108 netmatch = afswitch[af].af_netmatch; 109 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 110 if (ifp->int_flags & IFF_REMOTE) 111 continue; 112 if (af != ifp->int_addr.sa_family) 113 continue; 114 if ((*netmatch)(addr, &ifp->int_addr)) 115 break; 116 } 117 return (ifp); 118 } 119 120 /* 121 * Find an interface from which the specified address 122 * should have come from. Used for figuring out which 123 * interface a packet came in on -- for tracing. 124 */ 125 struct interface * 126 if_iflookup(addr) 127 struct sockaddr *addr; 128 { 129 register struct interface *ifp, *maybe; 130 register int af = addr->sa_family; 131 register int (*netmatch)(); 132 133 if (af >= af_max) 134 return (0); 135 maybe = 0; 136 netmatch = afswitch[af].af_netmatch; 137 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 138 if (ifp->int_addr.sa_family != af) 139 continue; 140 if (same(&ifp->int_addr, addr)) 141 break; 142 if ((ifp->int_flags & IFF_BROADCAST) && 143 same(&ifp->int_broadaddr, addr)) 144 break; 145 if ((ifp->int_flags & IFF_POINTOPOINT) && 146 same(&ifp->int_dstaddr, addr)) 147 break; 148 if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr)) 149 maybe = ifp; 150 } 151 if (ifp == 0) 152 ifp = maybe; 153 return (ifp); 154 } 155