1*6619Ssam /* if.c 4.15 82/05/04 */ 24944Swnj 34944Swnj #include "../h/param.h" 44944Swnj #include "../h/systm.h" 56333Ssam #include "../h/socket.h" 66582Ssam #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; 97*6619Ssam register int (*netmatch)(); 984944Swnj 99*6619Ssam if (af >= AF_MAX) 100*6619Ssam return (0); 101*6619Ssam netmatch = afswitch[af].af_netmatch; 1026333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 1036333Ssam if (af != ifp->if_addr.sa_family) 1046333Ssam continue; 1056333Ssam if ((*netmatch)(addr, &ifp->if_addr)) 1066333Ssam break; 1076333Ssam } 1086333Ssam return (ifp); 1096333Ssam } 1106333Ssam 1116333Ssam /* 1126333Ssam * As above, but parameter is network number. 1136333Ssam */ 1146333Ssam struct ifnet * 1156333Ssam if_ifonnetof(net) 1166333Ssam register int net; 1176333Ssam { 1186333Ssam register struct ifnet *ifp; 1196333Ssam 1204944Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 1214944Swnj if (ifp->if_net == net) 1224944Swnj break; 1234944Swnj return (ifp); 1244944Swnj } 1254944Swnj 1266333Ssam /* 1276333Ssam * Find an interface using a specific address family 1286333Ssam */ 1295083Swnj struct ifnet * 1306333Ssam if_ifwithaf(af) 1316333Ssam register int af; 1325083Swnj { 1336333Ssam register struct ifnet *ifp; 1345083Swnj 1356333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 1366333Ssam if (ifp->if_addr.sa_family == af) 1376333Ssam break; 1386333Ssam return (ifp); 1395083Swnj } 1405104Swnj 1416333Ssam /* 1426582Ssam * Mark an interface down and notify protocols of 1436582Ssam * the transition. 1446582Ssam */ 1456582Ssam if_down(ifp) 1466582Ssam register struct ifnet *ifp; 1476582Ssam { 1486582Ssam ifp->if_flags &= ~IFF_UP; 1496582Ssam pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 1506582Ssam } 1516582Ssam 1526582Ssam /* 1536333Ssam * Formulate an Internet address from network + host. Used in 1546333Ssam * building addresses stored in the ifnet structure. 1556333Ssam */ 1565104Swnj struct in_addr 1575104Swnj if_makeaddr(net, host) 1585104Swnj int net, host; 1595104Swnj { 1605104Swnj u_long addr; 1615104Swnj 1625104Swnj if (net < 128) 1635206Swnj addr = (net << 24) | host; 1645104Swnj else if (net < 65536) 1655206Swnj addr = (net << 16) | host; 1665104Swnj else 1675206Swnj addr = (net << 8) | host; 1685685Ssam #ifdef vax 1695104Swnj addr = htonl(addr); 1705685Ssam #endif 1715104Swnj return (*(struct in_addr *)&addr); 1725104Swnj } 1736363Ssam 1746363Ssam /* 1756363Ssam * Initialize an interface's routing 1766363Ssam * table entry according to the network. 1776363Ssam * INTERNET SPECIFIC. 1786363Ssam */ 1796363Ssam if_rtinit(ifp, flags) 1806363Ssam register struct ifnet *ifp; 1816363Ssam int flags; 1826363Ssam { 1836363Ssam struct sockaddr_in sin; 1846363Ssam 1856363Ssam if (ifp->if_flags & IFF_ROUTE) 1866363Ssam return; 1876363Ssam bzero((caddr_t)&sin, sizeof (sin)); 1886363Ssam sin.sin_family = AF_INET; 1896363Ssam sin.sin_addr = if_makeaddr(ifp->if_net, 0); 1906377Ssam rtinit(&sin, &ifp->if_addr, flags); 1916363Ssam } 192