1 /* in.c 6.4 84/08/29 */ 2 3 #include "param.h" 4 #include "mbuf.h" 5 #include "protosw.h" 6 #include "socket.h" 7 #include "socketvar.h" 8 #include "in.h" 9 #include "in_systm.h" 10 #include "../net/if.h" 11 #include "../net/route.h" 12 #include "../net/af.h" 13 14 #ifdef INET 15 inet_hash(sin, hp) 16 register struct sockaddr_in *sin; 17 struct afhash *hp; 18 { 19 20 hp->afh_nethash = in_netof(sin->sin_addr); 21 hp->afh_hosthash = ntohl(sin->sin_addr.s_addr); 22 } 23 24 inet_netmatch(sin1, sin2) 25 struct sockaddr_in *sin1, *sin2; 26 { 27 28 return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr)); 29 } 30 31 /* 32 * Formulate an Internet address from network + host. Used in 33 * building addresses stored in the ifnet structure. 34 */ 35 struct in_addr 36 if_makeaddr(net, host) 37 int net, host; 38 { 39 u_long addr; 40 41 if (net < IN_CLASSA_MAX) 42 addr = (net << IN_CLASSA_NSHIFT) | host; 43 else if (net < IN_CLASSB_MAX) 44 addr = (net << IN_CLASSB_NSHIFT) | host; 45 else 46 addr = (net << IN_CLASSC_NSHIFT) | host; 47 addr = htonl(addr); 48 return (*(struct in_addr *)&addr); 49 } 50 51 /* 52 * Return the network number from an internet address. 53 */ 54 in_netof(in) 55 struct in_addr in; 56 { 57 register u_long i = ntohl(in.s_addr); 58 register u_long net, subnet; 59 register struct ifnet *ifp; 60 61 if (IN_CLASSA(i)) { 62 net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; 63 if (IN_SUBNETA(i)) { 64 subnet = (i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT; 65 /* Fall through and check whether a subnet */ 66 } else 67 return (net); 68 } else if (IN_CLASSB(i)) { 69 net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; 70 if (IN_SUBNETB(i)) { 71 subnet = (i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT; 72 /* Fall through and check whether a subnet */ 73 } else 74 return (net); 75 } else { 76 return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); 77 } 78 79 /* 80 * Check whether network is a subnet of a `local' network; 81 * if so, return subnet number. 82 */ 83 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 84 if (ifp->if_addr.sa_family != AF_INET) 85 continue; 86 if (ifp->if_flags & IFF_LOCAL) { 87 if (ifp->if_net == net) 88 return (subnet); 89 if ((ifp->if_net >> SUBNETSHIFT) == net) 90 return (subnet); 91 /* 92 * Hack for use in setting if_net initially. 93 */ 94 if (ifp->if_net == 0) { 95 register struct sockaddr_in *sin; 96 sin = (struct sockaddr_in *) &ifp->if_addr; 97 if (sin->sin_addr.s_addr == in.s_addr) 98 return (subnet); 99 } 100 } 101 } 102 return (net); 103 } 104 105 /* 106 * Return the host portion of an internet address. 107 */ 108 in_lnaof(in) 109 struct in_addr in; 110 { 111 register u_long i = ntohl(in.s_addr); 112 register u_long net, host, subhost; 113 register struct ifnet *ifp; 114 115 if (IN_CLASSA(i)) { 116 if (IN_SUBNETA(i)) { 117 net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; 118 host = i & IN_CLASSA_HOST; 119 subhost = i & IN_CLASSA_SUBHOST; 120 /* Fall through and check whether a subnet */ 121 } else 122 return (i & IN_CLASSA_HOST); 123 } else if (IN_CLASSB(i)) { 124 if (IN_SUBNETB(i)) { 125 net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; 126 host = i & IN_CLASSB_HOST; 127 subhost = i & IN_CLASSB_SUBHOST; 128 /* Fall through and check whether a subnet */ 129 } else 130 return (i & IN_CLASSB_HOST); 131 } else { 132 return (i & IN_CLASSC_HOST); 133 } 134 135 /* 136 * Check whether network is a subnet of a `local' network; 137 * if so, use the modified interpretation of `host'. 138 */ 139 for (ifp = ifnet; ifp; ifp = ifp->if_next) { 140 if (ifp->if_addr.sa_family != AF_INET) 141 continue; 142 if (ifp->if_flags & IFF_LOCAL) { 143 if (ifp->if_net == net) 144 return (subhost); 145 if ((ifp->if_net >> SUBNETSHIFT) == net) 146 return (subhost); 147 } 148 } 149 return (host); 150 } 151 152 /* 153 * Initialize an interface's routing 154 * table entry according to the network. 155 * INTERNET SPECIFIC. 156 */ 157 if_rtinit(ifp, flags) 158 register struct ifnet *ifp; 159 int flags; 160 { 161 struct sockaddr_in sin; 162 163 if (ifp->if_flags & IFF_ROUTE) 164 return; 165 bzero((caddr_t)&sin, sizeof (sin)); 166 sin.sin_family = AF_INET; 167 sin.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); 168 rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags); 169 } 170 #endif 171