1*6582Ssam /* if.c 4.14 82/04/24 */ 24944Swnj 34944Swnj #include "../h/param.h" 44944Swnj #include "../h/systm.h" 56333Ssam #include "../h/socket.h" 6*6582Ssam #include "../h/protosw.h" 75083Swnj #include "../net/in.h" 85083Swnj #include "../net/in_systm.h" 94944Swnj #include "../net/if.h" 106333Ssam #include "../net/af.h" 114944Swnj 126207Swnj int ifqmaxlen = IFQ_MAXLEN; 136207Swnj 146333Ssam /* 156333Ssam * Network interface utility routines. 166333Ssam * 176333Ssam * Routines with if_ifwith* names take sockaddr *'s as 186333Ssam * parameters. Other routines take value parameters, 196333Ssam * e.g. if_ifwithnet takes the network number. 206333Ssam */ 216333Ssam 225206Swnj ifinit() 235206Swnj { 245206Swnj register struct ifnet *ifp; 255206Swnj 265206Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 276207Swnj if (ifp->if_init) { 286333Ssam (*ifp->if_init)(ifp->if_unit); 296207Swnj if (ifp->if_snd.ifq_maxlen == 0) 306207Swnj ifp->if_snd.ifq_maxlen = ifqmaxlen; 316207Swnj } 325206Swnj } 335206Swnj 346333Ssam /* 356333Ssam * Call each interface on a Unibus reset. 366333Ssam */ 375206Swnj ifubareset(uban) 385206Swnj int uban; 395206Swnj { 405206Swnj register struct ifnet *ifp; 415206Swnj 425206Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 435206Swnj if (ifp->if_ubareset) 445206Swnj (*ifp->if_ubareset)(uban); 455206Swnj } 465206Swnj 476333Ssam /* 486333Ssam * Attach an interface to the 496333Ssam * list of "active" interfaces. 506333Ssam */ 515160Swnj if_attach(ifp) 525160Swnj struct ifnet *ifp; 535160Swnj { 545698Swnj register struct ifnet **p = &ifnet; 555160Swnj 565160Swnj COUNT(IF_ATTACH); 575698Swnj while (*p) 585698Swnj p = &((*p)->if_next); 595698Swnj *p = ifp; 605160Swnj } 615160Swnj 626333Ssam /* 636333Ssam * Locate an interface based on a complete address. 646333Ssam */ 654951Swnj /*ARGSUSED*/ 664951Swnj struct ifnet * 676333Ssam if_ifwithaddr(addr) 686333Ssam struct sockaddr *addr; 694944Swnj { 704944Swnj register struct ifnet *ifp; 714944Swnj 724951Swnj COUNT(IF_IFWITHADDR); 736333Ssam #define equal(a1, a2) \ 746333Ssam (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 756333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 766333Ssam if (ifp->if_addr.sa_family != addr->sa_family) 776333Ssam continue; 786333Ssam if (equal(&ifp->if_addr, addr)) 794944Swnj break; 806333Ssam if ((ifp->if_flags & IFF_BROADCAST) && 816333Ssam equal(&ifp->if_broadaddr, addr)) 826333Ssam break; 836333Ssam } 844944Swnj return (ifp); 854944Swnj } 864944Swnj 876333Ssam /* 886333Ssam * Find an interface on a specific network. If many, choice 896333Ssam * is first found. 906333Ssam */ 914951Swnj struct ifnet * 926333Ssam if_ifwithnet(addr) 936333Ssam register struct sockaddr *addr; 944944Swnj { 954944Swnj register struct ifnet *ifp; 966333Ssam register int af = addr->sa_family; 976333Ssam register int (*netmatch)() = afswitch[af].af_netmatch; 984944Swnj 996333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 1006333Ssam if (af != ifp->if_addr.sa_family) 1016333Ssam continue; 1026333Ssam if ((*netmatch)(addr, &ifp->if_addr)) 1036333Ssam break; 1046333Ssam } 1056333Ssam return (ifp); 1066333Ssam } 1076333Ssam 1086333Ssam /* 1096333Ssam * As above, but parameter is network number. 1106333Ssam */ 1116333Ssam struct ifnet * 1126333Ssam if_ifonnetof(net) 1136333Ssam register int net; 1146333Ssam { 1156333Ssam register struct ifnet *ifp; 1166333Ssam 1174944Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 1184944Swnj if (ifp->if_net == net) 1194944Swnj break; 1204944Swnj return (ifp); 1214944Swnj } 1224944Swnj 1236333Ssam /* 1246333Ssam * Find an interface using a specific address family 1256333Ssam */ 1265083Swnj struct ifnet * 1276333Ssam if_ifwithaf(af) 1286333Ssam register int af; 1295083Swnj { 1306333Ssam register struct ifnet *ifp; 1315083Swnj 1326333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 1336333Ssam if (ifp->if_addr.sa_family == af) 1346333Ssam break; 1356333Ssam return (ifp); 1365083Swnj } 1375104Swnj 1386333Ssam /* 139*6582Ssam * Mark an interface down and notify protocols of 140*6582Ssam * the transition. 141*6582Ssam */ 142*6582Ssam if_down(ifp) 143*6582Ssam register struct ifnet *ifp; 144*6582Ssam { 145*6582Ssam ifp->if_flags &= ~IFF_UP; 146*6582Ssam pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 147*6582Ssam } 148*6582Ssam 149*6582Ssam /* 1506333Ssam * Formulate an Internet address from network + host. Used in 1516333Ssam * building addresses stored in the ifnet structure. 1526333Ssam */ 1535104Swnj struct in_addr 1545104Swnj if_makeaddr(net, host) 1555104Swnj int net, host; 1565104Swnj { 1575104Swnj u_long addr; 1585104Swnj 1595104Swnj if (net < 128) 1605206Swnj addr = (net << 24) | host; 1615104Swnj else if (net < 65536) 1625206Swnj addr = (net << 16) | host; 1635104Swnj else 1645206Swnj addr = (net << 8) | host; 1655685Ssam #ifdef vax 1665104Swnj addr = htonl(addr); 1675685Ssam #endif 1685104Swnj return (*(struct in_addr *)&addr); 1695104Swnj } 1706363Ssam 1716363Ssam /* 1726363Ssam * Initialize an interface's routing 1736363Ssam * table entry according to the network. 1746363Ssam * INTERNET SPECIFIC. 1756363Ssam */ 1766363Ssam if_rtinit(ifp, flags) 1776363Ssam register struct ifnet *ifp; 1786363Ssam int flags; 1796363Ssam { 1806363Ssam struct sockaddr_in sin; 1816363Ssam 1826363Ssam if (ifp->if_flags & IFF_ROUTE) 1836363Ssam return; 1846363Ssam bzero((caddr_t)&sin, sizeof (sin)); 1856363Ssam sin.sin_family = AF_INET; 1866363Ssam sin.sin_addr = if_makeaddr(ifp->if_net, 0); 1876377Ssam rtinit(&sin, &ifp->if_addr, flags); 1886363Ssam } 189