1*7264Ssam /* if.c 4.18 82/06/23 */ 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 565698Swnj while (*p) 575698Swnj p = &((*p)->if_next); 585698Swnj *p = ifp; 595160Swnj } 605160Swnj 616333Ssam /* 626333Ssam * Locate an interface based on a complete address. 636333Ssam */ 644951Swnj /*ARGSUSED*/ 654951Swnj struct ifnet * 666333Ssam if_ifwithaddr(addr) 676333Ssam struct sockaddr *addr; 684944Swnj { 694944Swnj register struct ifnet *ifp; 704944Swnj 716333Ssam #define equal(a1, a2) \ 726333Ssam (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 736333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 746333Ssam if (ifp->if_addr.sa_family != addr->sa_family) 756333Ssam continue; 766333Ssam if (equal(&ifp->if_addr, addr)) 774944Swnj break; 786333Ssam if ((ifp->if_flags & IFF_BROADCAST) && 796333Ssam equal(&ifp->if_broadaddr, addr)) 806333Ssam break; 816333Ssam } 824944Swnj return (ifp); 834944Swnj } 844944Swnj 856333Ssam /* 866333Ssam * Find an interface on a specific network. If many, choice 876333Ssam * is first found. 886333Ssam */ 894951Swnj struct ifnet * 906333Ssam if_ifwithnet(addr) 916333Ssam register struct sockaddr *addr; 924944Swnj { 934944Swnj register struct ifnet *ifp; 946333Ssam register int af = addr->sa_family; 956619Ssam register int (*netmatch)(); 964944Swnj 976619Ssam if (af >= AF_MAX) 986619Ssam return (0); 996619Ssam netmatch = afswitch[af].af_netmatch; 1006333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 1016333Ssam if (af != ifp->if_addr.sa_family) 1026333Ssam continue; 1036333Ssam if ((*netmatch)(addr, &ifp->if_addr)) 1046333Ssam break; 1056333Ssam } 1066333Ssam return (ifp); 1076333Ssam } 1086333Ssam 1096333Ssam /* 1106333Ssam * As above, but parameter is network number. 1116333Ssam */ 1126333Ssam struct ifnet * 1136333Ssam if_ifonnetof(net) 1146333Ssam register int net; 1156333Ssam { 1166333Ssam register struct ifnet *ifp; 1176333Ssam 1184944Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 1194944Swnj if (ifp->if_net == net) 1204944Swnj break; 1214944Swnj return (ifp); 1224944Swnj } 1234944Swnj 1246333Ssam /* 1256333Ssam * Find an interface using a specific address family 1266333Ssam */ 1275083Swnj struct ifnet * 1286333Ssam if_ifwithaf(af) 1296333Ssam register int af; 1305083Swnj { 1316333Ssam register struct ifnet *ifp; 1325083Swnj 1336333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 1346333Ssam if (ifp->if_addr.sa_family == af) 1356333Ssam break; 1366333Ssam return (ifp); 1375083Swnj } 1385104Swnj 1396333Ssam /* 1406582Ssam * Mark an interface down and notify protocols of 1416582Ssam * the transition. 1426582Ssam */ 1436582Ssam if_down(ifp) 1446582Ssam register struct ifnet *ifp; 1456582Ssam { 1466582Ssam ifp->if_flags &= ~IFF_UP; 1476582Ssam pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); 1486582Ssam } 149*7264Ssam 150*7264Ssam /* 151*7264Ssam * Handle interface watchdog timer routines. Called 152*7264Ssam * from softclock, we decrement timers (if set) and 153*7264Ssam * call the appropriate interface routine on expiration. 154*7264Ssam */ 155*7264Ssam if_slowtimo() 156*7264Ssam { 157*7264Ssam register struct ifnet *ifp; 158*7264Ssam 159*7264Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 160*7264Ssam if (ifp->if_timer && --ifp->if_timer == 0) { 161*7264Ssam if (ifp->if_watchdog == 0) { 162*7264Ssam printf("%s%d: no watchdog routine\n", 163*7264Ssam ifp->if_name, ifp->if_unit); 164*7264Ssam continue; 165*7264Ssam } 166*7264Ssam (*ifp->if_watchdog)(ifp->if_unit); 167*7264Ssam } 168*7264Ssam } 169