1 /* if.c 4.14 82/04/24 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/socket.h" 6 #include "../h/protosw.h" 7 #include "../net/in.h" 8 #include "../net/in_systm.h" 9 #include "../net/if.h" 10 #include "../net/af.h" 11 12 int ifqmaxlen = IFQ_MAXLEN; 13 14 /* 15 * Network interface utility routines. 16 * 17 * Routines with if_ifwith* names take sockaddr *'s as 18 * parameters. Other routines take value parameters, 19 * e.g. if_ifwithnet takes the network number. 20 */ 21 22 ifinit() 23 { 24 register struct ifnet *ifp; 25 26 for (ifp = ifnet; ifp; ifp = ifp->if_next) 27 if (ifp->if_init) { 28 (*ifp->if_init)(ifp->if_unit); 29 if (ifp->if_snd.ifq_maxlen == 0) 30 ifp->if_snd.ifq_maxlen = ifqmaxlen; 31 } 32 } 33 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 47 /* 48 * Attach an interface to the 49 * list of "active" interfaces. 50 */ 51 if_attach(ifp) 52 struct ifnet *ifp; 53 { 54 register struct ifnet **p = &ifnet; 55 56 COUNT(IF_ATTACH); 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 COUNT(IF_IFWITHADDR); 73 #define equal(a1, a2) \ 74 (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 75 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 76 if (ifp->if_addr.sa_family != addr->sa_family) 77 continue; 78 if (equal(&ifp->if_addr, addr)) 79 break; 80 if ((ifp->if_flags & IFF_BROADCAST) && 81 equal(&ifp->if_broadaddr, addr)) 82 break; 83 } 84 return (ifp); 85 } 86 87 /* 88 * Find an interface on a specific network. If many, choice 89 * is first found. 90 */ 91 struct ifnet * 92 if_ifwithnet(addr) 93 register struct sockaddr *addr; 94 { 95 register struct ifnet *ifp; 96 register int af = addr->sa_family; 97 register int (*netmatch)() = afswitch[af].af_netmatch; 98 99 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 100 if (af != ifp->if_addr.sa_family) 101 continue; 102 if ((*netmatch)(addr, &ifp->if_addr)) 103 break; 104 } 105 return (ifp); 106 } 107 108 /* 109 * As above, but parameter is network number. 110 */ 111 struct ifnet * 112 if_ifonnetof(net) 113 register int net; 114 { 115 register struct ifnet *ifp; 116 117 for (ifp = ifnet; ifp; ifp = ifp->if_next) 118 if (ifp->if_net == net) 119 break; 120 return (ifp); 121 } 122 123 /* 124 * Find an interface using a specific address family 125 */ 126 struct ifnet * 127 if_ifwithaf(af) 128 register int af; 129 { 130 register struct ifnet *ifp; 131 132 for (ifp = ifnet; ifp; ifp = ifp->if_next) 133 if (ifp->if_addr.sa_family == af) 134 break; 135 return (ifp); 136 } 137 138 /* 139 * Mark an interface down and notify protocols of 140 * the transition. 141 */ 142 if_down(ifp) 143 register struct ifnet *ifp; 144 { 145 ifp->if_flags &= ~IFF_UP; 146 pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 147 } 148 149 /* 150 * Formulate an Internet address from network + host. Used in 151 * building addresses stored in the ifnet structure. 152 */ 153 struct in_addr 154 if_makeaddr(net, host) 155 int net, host; 156 { 157 u_long addr; 158 159 if (net < 128) 160 addr = (net << 24) | host; 161 else if (net < 65536) 162 addr = (net << 16) | host; 163 else 164 addr = (net << 8) | host; 165 #ifdef vax 166 addr = htonl(addr); 167 #endif 168 return (*(struct in_addr *)&addr); 169 } 170 171 /* 172 * Initialize an interface's routing 173 * table entry according to the network. 174 * INTERNET SPECIFIC. 175 */ 176 if_rtinit(ifp, flags) 177 register struct ifnet *ifp; 178 int flags; 179 { 180 struct sockaddr_in sin; 181 182 if (ifp->if_flags & IFF_ROUTE) 183 return; 184 bzero((caddr_t)&sin, sizeof (sin)); 185 sin.sin_family = AF_INET; 186 sin.sin_addr = if_makeaddr(ifp->if_net, 0); 187 rtinit(&sin, &ifp->if_addr, flags); 188 } 189