1*6377Ssam /* if.c 4.13 82/03/30 */ 24944Swnj 34944Swnj #include "../h/param.h" 44944Swnj #include "../h/systm.h" 56333Ssam #include "../h/socket.h" 65083Swnj #include "../net/in.h" 75083Swnj #include "../net/in_systm.h" 84944Swnj #include "../net/if.h" 96333Ssam #include "../net/af.h" 104944Swnj 116207Swnj int ifqmaxlen = IFQ_MAXLEN; 126207Swnj 136333Ssam /* 146333Ssam * Network interface utility routines. 156333Ssam * 166333Ssam * Routines with if_ifwith* names take sockaddr *'s as 176333Ssam * parameters. Other routines take value parameters, 186333Ssam * e.g. if_ifwithnet takes the network number. 196333Ssam */ 206333Ssam 215206Swnj ifinit() 225206Swnj { 235206Swnj register struct ifnet *ifp; 245206Swnj 255206Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 266207Swnj if (ifp->if_init) { 276333Ssam (*ifp->if_init)(ifp->if_unit); 286207Swnj if (ifp->if_snd.ifq_maxlen == 0) 296207Swnj ifp->if_snd.ifq_maxlen = ifqmaxlen; 306207Swnj } 315206Swnj } 325206Swnj 336333Ssam /* 346333Ssam * Call each interface on a Unibus reset. 356333Ssam */ 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 466333Ssam /* 476333Ssam * Attach an interface to the 486333Ssam * list of "active" interfaces. 496333Ssam */ 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 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 714951Swnj COUNT(IF_IFWITHADDR); 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; 956333Ssam register int af = addr->sa_family; 966333Ssam register int (*netmatch)() = afswitch[af].af_netmatch; 974944Swnj 986333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) { 996333Ssam if (af != ifp->if_addr.sa_family) 1006333Ssam continue; 1016333Ssam if ((*netmatch)(addr, &ifp->if_addr)) 1026333Ssam break; 1036333Ssam } 1046333Ssam return (ifp); 1056333Ssam } 1066333Ssam 1076333Ssam /* 1086333Ssam * As above, but parameter is network number. 1096333Ssam */ 1106333Ssam struct ifnet * 1116333Ssam if_ifonnetof(net) 1126333Ssam register int net; 1136333Ssam { 1146333Ssam register struct ifnet *ifp; 1156333Ssam 1164944Swnj for (ifp = ifnet; ifp; ifp = ifp->if_next) 1174944Swnj if (ifp->if_net == net) 1184944Swnj break; 1194944Swnj return (ifp); 1204944Swnj } 1214944Swnj 1226333Ssam /* 1236333Ssam * Find an interface using a specific address family 1246333Ssam */ 1255083Swnj struct ifnet * 1266333Ssam if_ifwithaf(af) 1276333Ssam register int af; 1285083Swnj { 1296333Ssam register struct ifnet *ifp; 1305083Swnj 1316333Ssam for (ifp = ifnet; ifp; ifp = ifp->if_next) 1326333Ssam if (ifp->if_addr.sa_family == af) 1336333Ssam break; 1346333Ssam return (ifp); 1355083Swnj } 1365104Swnj 1376333Ssam /* 1386333Ssam * Formulate an Internet address from network + host. Used in 1396333Ssam * building addresses stored in the ifnet structure. 1406333Ssam */ 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 } 1586363Ssam 1596363Ssam /* 1606363Ssam * Initialize an interface's routing 1616363Ssam * table entry according to the network. 1626363Ssam * INTERNET SPECIFIC. 1636363Ssam */ 1646363Ssam if_rtinit(ifp, flags) 1656363Ssam register struct ifnet *ifp; 1666363Ssam int flags; 1676363Ssam { 1686363Ssam struct sockaddr_in sin; 1696363Ssam 1706363Ssam if (ifp->if_flags & IFF_ROUTE) 1716363Ssam return; 1726363Ssam bzero((caddr_t)&sin, sizeof (sin)); 1736363Ssam sin.sin_family = AF_INET; 1746363Ssam sin.sin_addr = if_makeaddr(ifp->if_net, 0); 175*6377Ssam rtinit(&sin, &ifp->if_addr, flags); 1766363Ssam } 177