1 /* 2 * Copyright (c) 1983 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * static char sccsid[] = "@(#)if.c 5.1 (Berkeley) 6/4/85"; (routed/if.c) 18 */ 19 20 #ifndef lint 21 static char sccsid[] = "@(#)if.c 5.1 (Berkeley) 09/20/88"; 22 #endif /* not lint */ 23 24 /* 25 * Routing Table Management Daemon 26 */ 27 #include "defs.h" 28 29 extern struct interface *ifnet; 30 31 /* 32 * Find the interface with address addr. 33 */ 34 struct interface * 35 if_ifwithaddr(addr) 36 struct sockaddr *addr; 37 { 38 register struct interface *ifp; 39 40 #define same(a1, a2) \ 41 (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 42 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 43 if (ifp->int_flags & IFF_REMOTE) 44 continue; 45 if (ifp->int_addr.sa_family != addr->sa_family) 46 continue; 47 if (same(&ifp->int_addr, addr)) 48 break; 49 if ((ifp->int_flags & IFF_BROADCAST) && 50 same(&ifp->int_broadaddr, addr)) 51 break; 52 } 53 return (ifp); 54 } 55 56 /* 57 * Find the point-to-point interface with destination address addr. 58 */ 59 struct interface * 60 if_ifwithdstaddr(addr) 61 struct sockaddr *addr; 62 { 63 register struct interface *ifp; 64 65 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 66 if ((ifp->int_flags & IFF_POINTOPOINT) == 0) 67 continue; 68 if (same(&ifp->int_dstaddr, addr)) 69 break; 70 } 71 return (ifp); 72 } 73 74 /* 75 * Find the interface on the network 76 * of the specified address. 77 */ 78 struct interface * 79 if_ifwithnet(addr) 80 register struct sockaddr *addr; 81 { 82 register struct interface *ifp; 83 register int af = addr->sa_family; 84 register int (*netmatch)(); 85 86 if (af >= AF_MAX) 87 return (0); 88 netmatch = afswitch[af].af_netmatch; 89 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 90 if (ifp->int_flags & IFF_REMOTE) 91 continue; 92 if (af != ifp->int_addr.sa_family) 93 continue; 94 if ((*netmatch)(addr, &ifp->int_addr)) 95 break; 96 } 97 return (ifp); 98 } 99 100 /* 101 * Find an interface from which the specified address 102 * should have come from. Used for figuring out which 103 * interface a packet came in on -- for tracing. 104 */ 105 struct interface * 106 if_iflookup(addr) 107 struct sockaddr *addr; 108 { 109 register struct interface *ifp, *maybe; 110 register int af = addr->sa_family; 111 register int (*netmatch)(); 112 113 if (af >= AF_MAX) 114 return (0); 115 maybe = 0; 116 netmatch = afswitch[af].af_netmatch; 117 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 118 if (ifp->int_addr.sa_family != af) 119 continue; 120 if (same(&ifp->int_addr, addr)) 121 break; 122 if ((ifp->int_flags & IFF_BROADCAST) && 123 same(&ifp->int_broadaddr, addr)) 124 break; 125 if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr)) 126 maybe = ifp; 127 } 128 if (ifp == 0) 129 ifp = maybe; 130 return (ifp); 131 } 132