1 /* if.c 4.15 82/05/04 */ 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)(); 98 99 if (af >= AF_MAX) 100 return (0); 101 netmatch = afswitch[af].af_netmatch; 102 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 103 if (af != ifp->if_addr.sa_family) 104 continue; 105 if ((*netmatch)(addr, &ifp->if_addr)) 106 break; 107 } 108 return (ifp); 109 } 110 111 /* 112 * As above, but parameter is network number. 113 */ 114 struct ifnet * 115 if_ifonnetof(net) 116 register int net; 117 { 118 register struct ifnet *ifp; 119 120 for (ifp = ifnet; ifp; ifp = ifp->if_next) 121 if (ifp->if_net == net) 122 break; 123 return (ifp); 124 } 125 126 /* 127 * Find an interface using a specific address family 128 */ 129 struct ifnet * 130 if_ifwithaf(af) 131 register int af; 132 { 133 register struct ifnet *ifp; 134 135 for (ifp = ifnet; ifp; ifp = ifp->if_next) 136 if (ifp->if_addr.sa_family == af) 137 break; 138 return (ifp); 139 } 140 141 /* 142 * Mark an interface down and notify protocols of 143 * the transition. 144 */ 145 if_down(ifp) 146 register struct ifnet *ifp; 147 { 148 ifp->if_flags &= ~IFF_UP; 149 pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 150 } 151 152 /* 153 * Formulate an Internet address from network + host. Used in 154 * building addresses stored in the ifnet structure. 155 */ 156 struct in_addr 157 if_makeaddr(net, host) 158 int net, host; 159 { 160 u_long addr; 161 162 if (net < 128) 163 addr = (net << 24) | host; 164 else if (net < 65536) 165 addr = (net << 16) | host; 166 else 167 addr = (net << 8) | host; 168 #ifdef vax 169 addr = htonl(addr); 170 #endif 171 return (*(struct in_addr *)&addr); 172 } 173 174 /* 175 * Initialize an interface's routing 176 * table entry according to the network. 177 * INTERNET SPECIFIC. 178 */ 179 if_rtinit(ifp, flags) 180 register struct ifnet *ifp; 181 int flags; 182 { 183 struct sockaddr_in sin; 184 185 if (ifp->if_flags & IFF_ROUTE) 186 return; 187 bzero((caddr_t)&sin, sizeof (sin)); 188 sin.sin_family = AF_INET; 189 sin.sin_addr = if_makeaddr(ifp->if_net, 0); 190 rtinit(&sin, &ifp->if_addr, flags); 191 } 192