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.8 (Berkeley) 06/01/90"; 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 RTF_HOST if the address is 107 * for an Internet host, RTF_SUBNET for a subnet, 108 * 0 for a network. 109 */ 110 inet_rtflags(sin) 111 struct sockaddr_in *sin; 112 { 113 register u_long i = ntohl(sin->sin_addr.s_addr); 114 register u_long net, host; 115 register struct interface *ifp; 116 117 if (IN_CLASSA(i)) { 118 net = i & IN_CLASSA_NET; 119 host = i & IN_CLASSA_HOST; 120 } else if (IN_CLASSB(i)) { 121 net = i & IN_CLASSB_NET; 122 host = i & IN_CLASSB_HOST; 123 } else { 124 net = i & IN_CLASSC_NET; 125 host = i & IN_CLASSC_HOST; 126 } 127 128 /* 129 * Check whether this network is subnetted; 130 * if so, check whether this is a subnet or a host. 131 */ 132 for (ifp = ifnet; ifp; ifp = ifp->int_next) 133 if (net == ifp->int_net) { 134 if (host &~ ifp->int_subnetmask) 135 return (RTF_HOST); 136 else if (ifp->int_subnetmask != ifp->int_netmask) 137 return (RTF_SUBNET); 138 else 139 return (0); /* network */ 140 } 141 if (host == 0) 142 return (0); /* network */ 143 else 144 return (RTF_HOST); 145 } 146 147 /* 148 * Return true if a route to subnet/host of route rt should be sent to dst. 149 * Send it only if dst is on the same logical network if not "internal", 150 * otherwise only if the route is the "internal" route for the logical net. 151 */ 152 inet_sendroute(rt, dst) 153 struct rt_entry *rt; 154 struct sockaddr_in *dst; 155 { 156 register u_long r = 157 ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); 158 register u_long d = ntohl(dst->sin_addr.s_addr); 159 160 if (IN_CLASSA(r)) { 161 if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) { 162 if ((r & IN_CLASSA_HOST) == 0) 163 return ((rt->rt_state & RTS_INTERNAL) == 0); 164 return (1); 165 } 166 if (r & IN_CLASSA_HOST) 167 return (0); 168 return ((rt->rt_state & RTS_INTERNAL) != 0); 169 } else if (IN_CLASSB(r)) { 170 if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) { 171 if ((r & IN_CLASSB_HOST) == 0) 172 return ((rt->rt_state & RTS_INTERNAL) == 0); 173 return (1); 174 } 175 if (r & IN_CLASSB_HOST) 176 return (0); 177 return ((rt->rt_state & RTS_INTERNAL) != 0); 178 } else { 179 if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) { 180 if ((r & IN_CLASSC_HOST) == 0) 181 return ((rt->rt_state & RTS_INTERNAL) == 0); 182 return (1); 183 } 184 if (r & IN_CLASSC_HOST) 185 return (0); 186 return ((rt->rt_state & RTS_INTERNAL) != 0); 187 } 188 } 189