1*8393Swnj /* if.c 4.20 82/10/09 */ 24944Swnj 34944Swnj #include "../h/param.h" 44944Swnj #include "../h/systm.h" 56333Ssam #include "../h/socket.h" 66582Ssam #include "../h/protosw.h" 74944Swnj #include "../net/if.h" 86333Ssam #include "../net/af.h" 94944Swnj 106207Swnj int ifqmaxlen = IFQ_MAXLEN; 116207Swnj 126333Ssam /* 136333Ssam * Network interface utility routines. 146333Ssam * 156333Ssam * Routines with if_ifwith* names take sockaddr *'s as 166333Ssam * parameters. Other routines take value parameters, 176333Ssam * e.g. if_ifwithnet takes the network number. 186333Ssam */ 196333Ssam 205206Swnj ifinit() 215206Swnj { 225206Swnj register struct ifnet *ifp; 235206Swnj 245206Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 256207Swnj if (ifp->if_init) { 266333Ssam (*ifp->if_init)(ifp->if_unit); 276207Swnj if (ifp->if_snd.ifq_maxlen == 0) 286207Swnj ifp->if_snd.ifq_maxlen = ifqmaxlen; 296207Swnj } 308173Sroot if_slowtimo(); 315206Swnj } 325206Swnj 33*8393Swnj #if vax 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 } 46*8393Swnj #endif 475206Swnj 486333Ssam /* 496333Ssam * Attach an interface to the 506333Ssam * list of "active" interfaces. 516333Ssam */ 525160Swnj if_attach(ifp) 535160Swnj struct ifnet *ifp; 545160Swnj { 555698Swnj register struct ifnet **p = &ifnet; 565160Swnj 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 726333Ssam #define equal(a1, a2) \ 736333Ssam (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 746333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 756333Ssam if (ifp->if_addr.sa_family != addr->sa_family) 766333Ssam continue; 776333Ssam if (equal(&ifp->if_addr, addr)) 784944Swnj break; 796333Ssam if ((ifp->if_flags & IFF_BROADCAST) && 806333Ssam equal(&ifp->if_broadaddr, addr)) 816333Ssam break; 826333Ssam } 834944Swnj return (ifp); 844944Swnj } 854944Swnj 866333Ssam /* 876333Ssam * Find an interface on a specific network. If many, choice 886333Ssam * is first found. 896333Ssam */ 904951Swnj struct ifnet * 916333Ssam if_ifwithnet(addr) 926333Ssam register struct sockaddr *addr; 934944Swnj { 944944Swnj register struct ifnet *ifp; 95*8393Swnj register u_int af = addr->sa_family; 966619Ssam register int (*netmatch)(); 974944Swnj 986619Ssam if (af >= AF_MAX) 996619Ssam return (0); 1006619Ssam netmatch = afswitch[af].af_netmatch; 1016333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 1026333Ssam if (af != ifp->if_addr.sa_family) 1036333Ssam continue; 1046333Ssam if ((*netmatch)(addr, &ifp->if_addr)) 1056333Ssam break; 1066333Ssam } 1076333Ssam return (ifp); 1086333Ssam } 1096333Ssam 1106333Ssam /* 1116333Ssam * As above, but parameter is network number. 1126333Ssam */ 1136333Ssam struct ifnet * 1146333Ssam if_ifonnetof(net) 1156333Ssam register int net; 1166333Ssam { 1176333Ssam register struct ifnet *ifp; 1186333Ssam 1194944Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 1204944Swnj if (ifp->if_net == net) 1214944Swnj break; 1224944Swnj return (ifp); 1234944Swnj } 1244944Swnj 1256333Ssam /* 1266333Ssam * Find an interface using a specific address family 1276333Ssam */ 1285083Swnj struct ifnet * 1296333Ssam if_ifwithaf(af) 1306333Ssam register int af; 1315083Swnj { 1326333Ssam register struct ifnet *ifp; 1335083Swnj 1346333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 1356333Ssam if (ifp->if_addr.sa_family == af) 1366333Ssam break; 1376333Ssam return (ifp); 1385083Swnj } 1395104Swnj 1406333Ssam /* 1416582Ssam * Mark an interface down and notify protocols of 1426582Ssam * the transition. 1436582Ssam */ 1446582Ssam if_down(ifp) 1456582Ssam register struct ifnet *ifp; 1466582Ssam { 1478173Sroot 1486582Ssam ifp->if_flags &= ~IFF_UP; 1496582Ssam pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 1506582Ssam } 1517264Ssam 1527264Ssam /* 1537264Ssam * Handle interface watchdog timer routines. Called 1547264Ssam * from softclock, we decrement timers (if set) and 1557264Ssam * call the appropriate interface routine on expiration. 1567264Ssam */ 1577264Ssam if_slowtimo() 1587264Ssam { 1597264Ssam register struct ifnet *ifp; 1607264Ssam 1617264Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 1627264Ssam if (ifp->if_timer && --ifp->if_timer == 0) { 1637264Ssam if (ifp->if_watchdog == 0) { 1647264Ssam printf("%s%d: no watchdog routine\n", 1657264Ssam ifp->if_name, ifp->if_unit); 1667264Ssam continue; 1677264Ssam } 1687264Ssam (*ifp->if_watchdog)(ifp->if_unit); 1697264Ssam } 1708173Sroot timeout(if_slowtimo, 0, hz / IFNET_SLOWHZ); 1717264Ssam } 172