1*16413Skarels /* in.c 6.3 84/04/24 */ 27159Ssam 37159Ssam #include "../h/param.h" 47159Ssam #include "../h/mbuf.h" 57159Ssam #include "../h/protosw.h" 67159Ssam #include "../h/socket.h" 77159Ssam #include "../h/socketvar.h" 88397Swnj #include "../netinet/in.h" 98397Swnj #include "../netinet/in_systm.h" 107166Ssam #include "../net/if.h" 117166Ssam #include "../net/route.h" 127159Ssam #include "../net/af.h" 137159Ssam 147159Ssam #ifdef INET 157159Ssam inet_hash(sin, hp) 167159Ssam register struct sockaddr_in *sin; 177159Ssam struct afhash *hp; 187159Ssam { 198595Sroot 207159Ssam hp->afh_nethash = in_netof(sin->sin_addr); 218937Sroot hp->afh_hosthash = ntohl(sin->sin_addr.s_addr); 227159Ssam } 237159Ssam 247159Ssam inet_netmatch(sin1, sin2) 257159Ssam struct sockaddr_in *sin1, *sin2; 267159Ssam { 278595Sroot 2811566Ssam return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr)); 297159Ssam } 307159Ssam 317159Ssam /* 327159Ssam * Formulate an Internet address from network + host. Used in 337159Ssam * building addresses stored in the ifnet structure. 347159Ssam */ 357159Ssam struct in_addr 367159Ssam if_makeaddr(net, host) 377159Ssam int net, host; 387159Ssam { 397159Ssam u_long addr; 407159Ssam 4116377Skarels if (net < IN_CLASSA_MAX) 428694Sroot addr = (net << IN_CLASSA_NSHIFT) | host; 4316377Skarels else if (net < IN_CLASSB_MAX) 448694Sroot addr = (net << IN_CLASSB_NSHIFT) | host; 457159Ssam else 468694Sroot addr = (net << IN_CLASSC_NSHIFT) | host; 477159Ssam addr = htonl(addr); 487159Ssam return (*(struct in_addr *)&addr); 497159Ssam } 507159Ssam 517159Ssam /* 528595Sroot * Return the network number from an internet address. 537159Ssam */ 547159Ssam in_netof(in) 557159Ssam struct in_addr in; 567159Ssam { 578937Sroot register u_long i = ntohl(in.s_addr); 58*16413Skarels register u_long net, subnet; 59*16413Skarels register struct ifnet *ifp; 607159Ssam 6116377Skarels if (IN_CLASSA(i)) { 62*16413Skarels net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; 63*16413Skarels if (IN_SUBNETA(i)) { 64*16413Skarels subnet = (i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT; 65*16413Skarels /* Fall through and check whether a subnet */ 66*16413Skarels } else 6716377Skarels return (net); 6816377Skarels } else if (IN_CLASSB(i)) { 69*16413Skarels net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; 70*16413Skarels if (IN_SUBNETB(i)) { 71*16413Skarels subnet = (i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT; 72*16413Skarels /* Fall through and check whether a subnet */ 73*16413Skarels } else 7416377Skarels return (net); 7516377Skarels } else { 76*16413Skarels return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); 7716377Skarels } 78*16413Skarels 79*16413Skarels /* 80*16413Skarels * Check whether network is a subnet of a `local' network; 81*16413Skarels * if so, return subnet number. 82*16413Skarels */ 83*16413Skarels for (ifp = ifnet; ifp; ifp = ifp->if_next) { 84*16413Skarels if (ifp->if_addr.sa_family != AF_INET) 85*16413Skarels continue; 86*16413Skarels if (ifp->if_flags & IFF_LOCAL) { 87*16413Skarels if (ifp->if_net == net) 88*16413Skarels return (subnet); 89*16413Skarels if ((ifp->if_net >> SUBNETSHIFT) == net) 90*16413Skarels return (subnet); 91*16413Skarels /* 92*16413Skarels * Hack for use in setting if_net initially. 93*16413Skarels */ 94*16413Skarels if (ifp->if_net == 0) { 95*16413Skarels register struct sockaddr_in *sin; 96*16413Skarels sin = (struct sockaddr_in *) &ifp->if_addr; 97*16413Skarels if (sin->sin_addr.s_addr == in.s_addr) 98*16413Skarels return (subnet); 99*16413Skarels } 100*16413Skarels } 101*16413Skarels } 102*16413Skarels return (net); 1037159Ssam } 1047159Ssam 1057159Ssam /* 1068595Sroot * Return the host portion of an internet address. 1077159Ssam */ 1087159Ssam in_lnaof(in) 1097159Ssam struct in_addr in; 1107159Ssam { 1118937Sroot register u_long i = ntohl(in.s_addr); 112*16413Skarels register u_long net, host, subhost; 113*16413Skarels register struct ifnet *ifp; 1147159Ssam 11516377Skarels if (IN_CLASSA(i)) { 116*16413Skarels if (IN_SUBNETA(i)) { 117*16413Skarels net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; 118*16413Skarels host = i & IN_CLASSA_HOST; 119*16413Skarels subhost = i & IN_CLASSA_SUBHOST; 120*16413Skarels /* Fall through and check whether a subnet */ 121*16413Skarels } else 122*16413Skarels return (i & IN_CLASSA_HOST); 12316377Skarels } else if (IN_CLASSB(i)) { 124*16413Skarels if (IN_SUBNETB(i)) { 125*16413Skarels net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; 126*16413Skarels host = i & IN_CLASSB_HOST; 127*16413Skarels subhost = i & IN_CLASSB_SUBHOST; 128*16413Skarels /* Fall through and check whether a subnet */ 129*16413Skarels } else 130*16413Skarels return (i & IN_CLASSB_HOST); 13116377Skarels } else { 132*16413Skarels return (i & IN_CLASSC_HOST); 13316377Skarels } 1347159Ssam 135*16413Skarels /* 136*16413Skarels * Check whether network is a subnet of a `local' network; 137*16413Skarels * if so, use the modified interpretation of `host'. 138*16413Skarels */ 13916377Skarels for (ifp = ifnet; ifp; ifp = ifp->if_next) { 14016377Skarels if (ifp->if_addr.sa_family != AF_INET) 14116377Skarels continue; 14216377Skarels if (ifp->if_flags & IFF_LOCAL) { 14316377Skarels if (ifp->if_net == net) 144*16413Skarels return (subhost); 14516377Skarels if ((ifp->if_net >> SUBNETSHIFT) == net) 146*16413Skarels return (subhost); 14716377Skarels } 14816377Skarels } 149*16413Skarels return (host); 15016377Skarels } 15116377Skarels 15216377Skarels /* 1537159Ssam * Initialize an interface's routing 1547159Ssam * table entry according to the network. 1557159Ssam * INTERNET SPECIFIC. 1567159Ssam */ 1577159Ssam if_rtinit(ifp, flags) 1587159Ssam register struct ifnet *ifp; 1597159Ssam int flags; 1607159Ssam { 1617159Ssam struct sockaddr_in sin; 1627159Ssam 1637159Ssam if (ifp->if_flags & IFF_ROUTE) 1647159Ssam return; 1657159Ssam bzero((caddr_t)&sin, sizeof (sin)); 1667159Ssam sin.sin_family = AF_INET; 16711566Ssam sin.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); 1688637Sroot rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags); 1697159Ssam } 1707159Ssam #endif 171