1*6333Ssam /* if.c 4.11 82/03/28 */ 24944Swnj 34944Swnj #include "../h/param.h" 44944Swnj #include "../h/systm.h" 5*6333Ssam #include "../h/socket.h" 65083Swnj #include "../net/in.h" 75083Swnj #include "../net/in_systm.h" 84944Swnj #include "../net/if.h" 9*6333Ssam #include "../net/af.h" 104944Swnj 116207Swnj int ifqmaxlen = IFQ_MAXLEN; 126207Swnj 13*6333Ssam /* 14*6333Ssam * Network interface utility routines. 15*6333Ssam * 16*6333Ssam * Routines with if_ifwith* names take sockaddr *'s as 17*6333Ssam * parameters. Other routines take value parameters, 18*6333Ssam * e.g. if_ifwithnet takes the network number. 19*6333Ssam */ 20*6333Ssam 215206Swnj ifinit() 225206Swnj { 235206Swnj register struct ifnet *ifp; 245206Swnj 255206Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 266207Swnj if (ifp->if_init) { 27*6333Ssam (*ifp->if_init)(ifp->if_unit); 286207Swnj if (ifp->if_snd.ifq_maxlen == 0) 296207Swnj ifp->if_snd.ifq_maxlen = ifqmaxlen; 306207Swnj } 315206Swnj } 325206Swnj 33*6333Ssam /* 34*6333Ssam * Call each interface on a Unibus reset. 35*6333Ssam */ 365206Swnj ifubareset(uban) 375206Swnj int uban; 385206Swnj { 395206Swnj register struct ifnet *ifp; 405206Swnj 415206Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 425206Swnj if (ifp->if_ubareset) 435206Swnj (*ifp->if_ubareset)(uban); 445206Swnj } 455206Swnj 46*6333Ssam /* 47*6333Ssam * Attach an interface to the 48*6333Ssam * list of "active" interfaces. 49*6333Ssam */ 505160Swnj if_attach(ifp) 515160Swnj struct ifnet *ifp; 525160Swnj { 535698Swnj register struct ifnet **p = &ifnet; 545160Swnj 555160Swnj COUNT(IF_ATTACH); 565698Swnj while (*p) 575698Swnj p = &((*p)->if_next); 585698Swnj *p = ifp; 595160Swnj } 605160Swnj 61*6333Ssam /* 62*6333Ssam * Locate an interface based on a complete address. 63*6333Ssam */ 644951Swnj /*ARGSUSED*/ 654951Swnj struct ifnet * 66*6333Ssam if_ifwithaddr(addr) 67*6333Ssam struct sockaddr *addr; 684944Swnj { 694944Swnj register struct ifnet *ifp; 704944Swnj 714951Swnj COUNT(IF_IFWITHADDR); 72*6333Ssam #define equal(a1, a2) \ 73*6333Ssam (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) 74*6333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 75*6333Ssam if (ifp->if_addr.sa_family != addr->sa_family) 76*6333Ssam continue; 77*6333Ssam if (equal(&ifp->if_addr, addr)) 784944Swnj break; 79*6333Ssam if ((ifp->if_flags & IFF_BROADCAST) && 80*6333Ssam equal(&ifp->if_broadaddr, addr)) 81*6333Ssam break; 82*6333Ssam } 834944Swnj return (ifp); 844944Swnj } 854944Swnj 86*6333Ssam /* 87*6333Ssam * Find an interface on a specific network. If many, choice 88*6333Ssam * is first found. 89*6333Ssam */ 904951Swnj struct ifnet * 91*6333Ssam if_ifwithnet(addr) 92*6333Ssam register struct sockaddr *addr; 934944Swnj { 944944Swnj register struct ifnet *ifp; 95*6333Ssam register int af = addr->sa_family; 96*6333Ssam register int (*netmatch)() = afswitch[af].af_netmatch; 974944Swnj 98*6333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 99*6333Ssam if (af != ifp->if_addr.sa_family) 100*6333Ssam continue; 101*6333Ssam if ((*netmatch)(addr, &ifp->if_addr)) 102*6333Ssam break; 103*6333Ssam } 104*6333Ssam return (ifp); 105*6333Ssam } 106*6333Ssam 107*6333Ssam /* 108*6333Ssam * As above, but parameter is network number. 109*6333Ssam */ 110*6333Ssam struct ifnet * 111*6333Ssam if_ifonnetof(net) 112*6333Ssam register int net; 113*6333Ssam { 114*6333Ssam register struct ifnet *ifp; 115*6333Ssam 1164944Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 1174944Swnj if (ifp->if_net == net) 1184944Swnj break; 1194944Swnj return (ifp); 1204944Swnj } 1214944Swnj 122*6333Ssam /* 123*6333Ssam * Find an interface using a specific address family 124*6333Ssam */ 1255083Swnj struct ifnet * 126*6333Ssam if_ifwithaf(af) 127*6333Ssam register int af; 1285083Swnj { 129*6333Ssam register struct ifnet *ifp; 1305083Swnj 131*6333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 132*6333Ssam if (ifp->if_addr.sa_family == af) 133*6333Ssam break; 134*6333Ssam return (ifp); 1355083Swnj } 1365104Swnj 137*6333Ssam /* 138*6333Ssam * Formulate an Internet address from network + host. Used in 139*6333Ssam * building addresses stored in the ifnet structure. 140*6333Ssam */ 1415104Swnj struct in_addr 1425104Swnj if_makeaddr(net, host) 1435104Swnj int net, host; 1445104Swnj { 1455104Swnj u_long addr; 1465104Swnj 1475104Swnj if (net < 128) 1485206Swnj addr = (net << 24) | host; 1495104Swnj else if (net < 65536) 1505206Swnj addr = (net << 16) | host; 1515104Swnj else 1525206Swnj addr = (net << 8) | host; 1535685Ssam #ifdef vax 1545104Swnj addr = htonl(addr); 1555685Ssam #endif 1565104Swnj return (*(struct in_addr *)&addr); 1575104Swnj } 158