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