1 /* if.c 4.21 82/10/17 */ 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_ubareset) 44 (*ifp->if_ubareset)(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 */ 144 if_down(ifp) 145 register struct ifnet *ifp; 146 { 147 148 ifp->if_flags &= ~IFF_UP; 149 pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 150 } 151 152 /* 153 * Handle interface watchdog timer routines. Called 154 * from softclock, we decrement timers (if set) and 155 * call the appropriate interface routine on expiration. 156 */ 157 if_slowtimo() 158 { 159 register struct ifnet *ifp; 160 161 for (ifp = ifnet; ifp; ifp = ifp->if_next) 162 if (ifp->if_timer && --ifp->if_timer == 0) { 163 if (ifp->if_watchdog == 0) { 164 printf("%s%d: no watchdog routine\n", 165 ifp->if_name, ifp->if_unit); 166 continue; 167 } 168 (*ifp->if_watchdog)(ifp->if_unit); 169 } 170 timeout(if_slowtimo, 0, hz / IFNET_SLOWHZ); 171 } 172