1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)inet.c 5.10 (Berkeley) 03/11/92"; 10 #endif /* not lint */ 11 12 /* 13 * Temporarily, copy these routines from the kernel, 14 * as we need to know about subnets. 15 */ 16 #include "defs.h" 17 18 extern struct interface *ifnet; 19 20 /* 21 * Formulate an Internet address from network + host. 22 */ 23 struct in_addr 24 inet_makeaddr(net, host) 25 u_long net, host; 26 { 27 register struct interface *ifp; 28 register u_long mask; 29 u_long addr; 30 31 if (IN_CLASSA(net)) 32 mask = IN_CLASSA_HOST; 33 else if (IN_CLASSB(net)) 34 mask = IN_CLASSB_HOST; 35 else 36 mask = IN_CLASSC_HOST; 37 for (ifp = ifnet; ifp; ifp = ifp->int_next) 38 if ((ifp->int_netmask & net) == ifp->int_net) { 39 mask = ~ifp->int_subnetmask; 40 break; 41 } 42 addr = net | (host & mask); 43 addr = htonl(addr); 44 return (*(struct in_addr *)&addr); 45 } 46 47 /* 48 * Return the network number from an internet address. 49 */ 50 inet_netof(in) 51 struct in_addr in; 52 { 53 register u_long i = ntohl(in.s_addr); 54 register u_long net; 55 register struct interface *ifp; 56 57 if (IN_CLASSA(i)) 58 net = i & IN_CLASSA_NET; 59 else if (IN_CLASSB(i)) 60 net = i & IN_CLASSB_NET; 61 else 62 net = i & IN_CLASSC_NET; 63 64 /* 65 * Check whether network is a subnet; 66 * if so, return subnet number. 67 */ 68 for (ifp = ifnet; ifp; ifp = ifp->int_next) 69 if ((ifp->int_netmask & net) == ifp->int_net) 70 return (i & ifp->int_subnetmask); 71 return (net); 72 } 73 74 /* 75 * Return the host portion of an internet address. 76 */ 77 inet_lnaof(in) 78 struct in_addr in; 79 { 80 register u_long i = ntohl(in.s_addr); 81 register u_long net, host; 82 register struct interface *ifp; 83 84 if (IN_CLASSA(i)) { 85 net = i & IN_CLASSA_NET; 86 host = i & IN_CLASSA_HOST; 87 } else if (IN_CLASSB(i)) { 88 net = i & IN_CLASSB_NET; 89 host = i & IN_CLASSB_HOST; 90 } else { 91 net = i & IN_CLASSC_NET; 92 host = i & IN_CLASSC_HOST; 93 } 94 95 /* 96 * Check whether network is a subnet; 97 * if so, use the modified interpretation of `host'. 98 */ 99 for (ifp = ifnet; ifp; ifp = ifp->int_next) 100 if ((ifp->int_netmask & net) == ifp->int_net) 101 return (host &~ ifp->int_subnetmask); 102 return (host); 103 } 104 105 /* 106 * Return the netmask pertaining to an internet address. 107 */ 108 inet_maskof(in) 109 struct in_addr in; 110 { 111 register u_long i = ntohl(in.s_addr); 112 register u_long mask; 113 register struct interface *ifp; 114 115 if (i == 0) { 116 mask = 0; 117 } else if (IN_CLASSA(i)) { 118 mask = IN_CLASSA_NET; 119 } else if (IN_CLASSB(i)) { 120 mask = i & IN_CLASSB_NET; 121 } else 122 mask = i & IN_CLASSC_NET; 123 124 /* 125 * Check whether network is a subnet; 126 * if so, use the modified interpretation of `host'. 127 */ 128 for (ifp = ifnet; ifp; ifp = ifp->int_next) 129 if ((ifp->int_netmask & i) == ifp->int_net) 130 mask = ifp->int_subnetmask; 131 return (htonl(mask)); 132 } 133 134 /* 135 * Return RTF_HOST if the address is 136 * for an Internet host, RTF_SUBNET for a subnet, 137 * 0 for a network. 138 */ 139 inet_rtflags(sin) 140 struct sockaddr_in *sin; 141 { 142 register u_long i = ntohl(sin->sin_addr.s_addr); 143 register u_long net, host; 144 register struct interface *ifp; 145 146 if (IN_CLASSA(i)) { 147 net = i & IN_CLASSA_NET; 148 host = i & IN_CLASSA_HOST; 149 } else if (IN_CLASSB(i)) { 150 net = i & IN_CLASSB_NET; 151 host = i & IN_CLASSB_HOST; 152 } else { 153 net = i & IN_CLASSC_NET; 154 host = i & IN_CLASSC_HOST; 155 } 156 157 /* 158 * Check whether this network is subnetted; 159 * if so, check whether this is a subnet or a host. 160 */ 161 for (ifp = ifnet; ifp; ifp = ifp->int_next) 162 if (net == ifp->int_net) { 163 if (host &~ ifp->int_subnetmask) 164 return (RTF_HOST); 165 else if (ifp->int_subnetmask != ifp->int_netmask) 166 return (RTF_SUBNET); 167 else 168 return (0); /* network */ 169 } 170 if (host == 0) 171 return (0); /* network */ 172 else 173 return (RTF_HOST); 174 } 175 176 /* 177 * Return true if a route to subnet/host of route rt should be sent to dst. 178 * Send it only if dst is on the same logical network if not "internal", 179 * otherwise only if the route is the "internal" route for the logical net. 180 */ 181 inet_sendroute(rt, dst) 182 struct rt_entry *rt; 183 struct sockaddr_in *dst; 184 { 185 register u_long r = 186 ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); 187 register u_long d = ntohl(dst->sin_addr.s_addr); 188 189 if (IN_CLASSA(r)) { 190 if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) { 191 if ((r & IN_CLASSA_HOST) == 0) 192 return ((rt->rt_state & RTS_INTERNAL) == 0); 193 return (1); 194 } 195 if (r & IN_CLASSA_HOST) 196 return (0); 197 return ((rt->rt_state & RTS_INTERNAL) != 0); 198 } else if (IN_CLASSB(r)) { 199 if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) { 200 if ((r & IN_CLASSB_HOST) == 0) 201 return ((rt->rt_state & RTS_INTERNAL) == 0); 202 return (1); 203 } 204 if (r & IN_CLASSB_HOST) 205 return (0); 206 return ((rt->rt_state & RTS_INTERNAL) != 0); 207 } else { 208 if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) { 209 if ((r & IN_CLASSC_HOST) == 0) 210 return ((rt->rt_state & RTS_INTERNAL) == 0); 211 return (1); 212 } 213 if (r & IN_CLASSC_HOST) 214 return (0); 215 return ((rt->rt_state & RTS_INTERNAL) != 0); 216 } 217 } 218