1 /* if.c 4.24 82/11/13 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/socket.h" 6 #include "../h/protosw.h" 7 #include "../net/if.h" 8 #include "../net/af.h" 9 10 int ifqmaxlen = IFQ_MAXLEN; 11 12 /* 13 * Network interface utility routines. 14 * 15 * Routines with if_ifwith* names take sockaddr *'s as 16 * parameters. Other routines take value parameters, 17 * e.g. if_ifwithnet takes the network number. 18 */ 19 20 ifinit() 21 { 22 register struct ifnet *ifp; 23 24 for (ifp = ifnet; ifp; ifp = ifp->if_next) 25 if (ifp->if_init) { 26 (*ifp->if_init)(ifp->if_unit); 27 if (ifp->if_snd.ifq_maxlen == 0) 28 ifp->if_snd.ifq_maxlen = ifqmaxlen; 29 } 30 if_slowtimo(); 31 } 32 33 #if vax 34 /* 35 * Call each interface on a Unibus reset. 36 */ 37 ifubareset(uban) 38 int uban; 39 { 40 register struct ifnet *ifp; 41 42 for (ifp = ifnet; ifp; ifp = ifp->if_next) 43 if (ifp->if_reset) 44 (*ifp->if_reset)(uban); 45 } 46 #endif 47 48 /* 49 * Attach an interface to the 50 * list of "active" interfaces. 51 */ 52 if_attach(ifp) 53 struct ifnet *ifp; 54 { 55 register struct ifnet **p = &ifnet; 56 57 while (*p) 58 p = &((*p)->if_next); 59 *p = ifp; 60 } 61 62 /* 63 * Locate an interface based on a complete address. 64 */ 65 /*ARGSUSED*/ 66 struct ifnet * 67 if_ifwithaddr(addr) 68 struct sockaddr *addr; 69 { 70 register struct ifnet *ifp; 71 72 #define equal(a1, a2) \ 73 (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 74 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 75 if (ifp->if_addr.sa_family != addr->sa_family) 76 continue; 77 if (equal(&ifp->if_addr, addr)) 78 break; 79 if ((ifp->if_flags & IFF_BROADCAST) && 80 equal(&ifp->if_broadaddr, addr)) 81 break; 82 } 83 return (ifp); 84 } 85 86 /* 87 * Find an interface on a specific network. If many, choice 88 * is first found. 89 */ 90 struct ifnet * 91 if_ifwithnet(addr) 92 register struct sockaddr *addr; 93 { 94 register struct ifnet *ifp; 95 register u_int af = addr->sa_family; 96 register int (*netmatch)(); 97 98 if (af >= AF_MAX) 99 return (0); 100 netmatch = afswitch[af].af_netmatch; 101 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 102 if (af != ifp->if_addr.sa_family) 103 continue; 104 if ((*netmatch)(addr, &ifp->if_addr)) 105 break; 106 } 107 return (ifp); 108 } 109 110 /* 111 * As above, but parameter is network number. 112 */ 113 struct ifnet * 114 if_ifonnetof(net) 115 register int net; 116 { 117 register struct ifnet *ifp; 118 119 for (ifp = ifnet; ifp; ifp = ifp->if_next) 120 if (ifp->if_net == net) 121 break; 122 return (ifp); 123 } 124 125 /* 126 * Find an interface using a specific address family 127 */ 128 struct ifnet * 129 if_ifwithaf(af) 130 register int af; 131 { 132 register struct ifnet *ifp; 133 134 for (ifp = ifnet; ifp; ifp = ifp->if_next) 135 if (ifp->if_addr.sa_family == af) 136 break; 137 return (ifp); 138 } 139 140 /* 141 * Mark an interface down and notify protocols of 142 * the transition. 143 * NOTE: must be called at splnet or eqivalent. 144 */ 145 if_down(ifp) 146 register struct ifnet *ifp; 147 { 148 149 ifp->if_flags &= ~IFF_UP; 150 pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 151 } 152 153 /* 154 * Handle interface watchdog timer routines. Called 155 * from softclock, we decrement timers (if set) and 156 * call the appropriate interface routine on expiration. 157 */ 158 if_slowtimo() 159 { 160 register struct ifnet *ifp; 161 162 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 163 if (ifp->if_timer == 0 || --ifp->if_timer) 164 continue; 165 if (ifp->if_watchdog) 166 (*ifp->if_watchdog)(ifp->if_unit); 167 } 168 timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ); 169 } 170