121994Sdist /* 221994Sdist * Copyright (c) 1983 Regents of the University of California. 321994Sdist * All rights reserved. The Berkeley software License Agreement 421994Sdist * specifies the terms and conditions for redistribution. 521994Sdist */ 621994Sdist 716395Skarels #ifndef lint 8*28994Skarels static char sccsid[] = "@(#)inet.c 5.4 (Berkeley) 06/03/86"; 921994Sdist #endif not lint 1021994Sdist 1116395Skarels /* 1216395Skarels * Temporarily, copy these routines from the kernel, 1316395Skarels * as we need to know about subnets. 1416395Skarels */ 1516395Skarels #include "defs.h" 1616395Skarels 1721846Skarels extern struct interface *ifnet; 1821846Skarels 1916395Skarels /* 2021846Skarels * Formulate an Internet address from network + host. 2116395Skarels */ 2216395Skarels struct in_addr 2321846Skarels inet_makeaddr(net, host) 2421846Skarels u_long net, host; 2516395Skarels { 2621846Skarels register struct interface *ifp; 2721846Skarels register u_long mask; 2816395Skarels u_long addr; 2916395Skarels 3021846Skarels if (IN_CLASSA(net)) 3121846Skarels mask = IN_CLASSA_HOST; 3221846Skarels else if (IN_CLASSB(net)) 3321846Skarels mask = IN_CLASSB_HOST; 3416395Skarels else 3521846Skarels mask = IN_CLASSC_HOST; 3621846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 3721846Skarels if ((ifp->int_netmask & net) == ifp->int_net) { 3821846Skarels mask = ~ifp->int_subnetmask; 3921846Skarels break; 4021846Skarels } 4121846Skarels addr = net | (host & mask); 4216395Skarels addr = htonl(addr); 4316395Skarels return (*(struct in_addr *)&addr); 4416395Skarels } 4516395Skarels 4616395Skarels /* 4716395Skarels * Return the network number from an internet address. 4816395Skarels */ 4916395Skarels inet_netof(in) 5016395Skarels struct in_addr in; 5116395Skarels { 5216395Skarels register u_long i = ntohl(in.s_addr); 5321846Skarels register u_long net; 5416429Skarels register struct interface *ifp; 5516395Skarels 5621846Skarels if (IN_CLASSA(i)) 5721846Skarels net = i & IN_CLASSA_NET; 5821846Skarels else if (IN_CLASSB(i)) 5921846Skarels net = i & IN_CLASSB_NET; 6021846Skarels else 6121846Skarels net = i & IN_CLASSC_NET; 6216429Skarels 6316429Skarels /* 6421846Skarels * Check whether network is a subnet; 6516429Skarels * if so, return subnet number. 6616429Skarels */ 6721846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 6821846Skarels if ((ifp->int_netmask & net) == ifp->int_net) 6921846Skarels return (i & ifp->int_subnetmask); 7016429Skarels return (net); 7116395Skarels } 7216395Skarels 7316395Skarels /* 7416395Skarels * Return the host portion of an internet address. 7516395Skarels */ 7616395Skarels inet_lnaof(in) 7716395Skarels struct in_addr in; 7816395Skarels { 7916395Skarels register u_long i = ntohl(in.s_addr); 8021846Skarels register u_long net, host; 8116429Skarels register struct interface *ifp; 8216395Skarels 8316395Skarels if (IN_CLASSA(i)) { 8421846Skarels net = i & IN_CLASSA_NET; 8521846Skarels host = i & IN_CLASSA_HOST; 8616395Skarels } else if (IN_CLASSB(i)) { 8721846Skarels net = i & IN_CLASSB_NET; 8821846Skarels host = i & IN_CLASSB_HOST; 8916395Skarels } else { 9021846Skarels net = i & IN_CLASSC_NET; 9121846Skarels host = i & IN_CLASSC_HOST; 9216395Skarels } 9316395Skarels 9416429Skarels /* 9521846Skarels * Check whether network is a subnet; 9616429Skarels * if so, use the modified interpretation of `host'. 9716429Skarels */ 9821846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 9921846Skarels if ((ifp->int_netmask & net) == ifp->int_net) 10021846Skarels return (host &~ ifp->int_subnetmask); 10116429Skarels return (host); 10216395Skarels } 10327231Skarels 10427231Skarels /* 10527231Skarels * Return RTF_HOST if the address is 10627231Skarels * for an Internet host, RTF_SUBNET for a subnet, 10727231Skarels * 0 for a network. 10827231Skarels */ 10927231Skarels inet_rtflags(sin) 11027231Skarels struct sockaddr_in *sin; 11127231Skarels { 11227231Skarels register u_long i = ntohl(sin->sin_addr.s_addr); 11327231Skarels register u_long net, host; 11427231Skarels register struct interface *ifp; 11527231Skarels 11627231Skarels if (IN_CLASSA(i)) { 11727231Skarels net = i & IN_CLASSA_NET; 11827231Skarels host = i & IN_CLASSA_HOST; 11927231Skarels } else if (IN_CLASSB(i)) { 12027231Skarels net = i & IN_CLASSB_NET; 12127231Skarels host = i & IN_CLASSB_HOST; 12227231Skarels } else { 12327231Skarels net = i & IN_CLASSC_NET; 12427231Skarels host = i & IN_CLASSC_HOST; 12527231Skarels } 12627231Skarels 12727231Skarels /* 12827231Skarels * Check whether this network is subnetted; 12927231Skarels * if so, check whether this is a subnet or a host. 13027231Skarels */ 13127231Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 13227231Skarels if (net == ifp->int_net) { 133*28994Skarels if (host &~ ifp->int_subnetmask) 134*28994Skarels return (RTF_HOST); 135*28994Skarels else if (ifp->int_subnetmask != ifp->int_netmask) 13627231Skarels return (RTF_SUBNET); 13727231Skarels else 138*28994Skarels return (0); /* network */ 13927231Skarels } 140*28994Skarels if (host == 0) 141*28994Skarels return (0); /* network */ 142*28994Skarels else 143*28994Skarels return (RTF_HOST); 14427231Skarels } 14527231Skarels 14627231Skarels /* 147*28994Skarels * Return true if a route to subnet of route rt should be sent to dst. 14827231Skarels * Send it only if dst is on the same logical network, 149*28994Skarels * or the route is the "internal" route for the net. 15027231Skarels */ 15128906Skarels inet_sendsubnet(rt, dst) 15228906Skarels struct rt_entry *rt; 15328906Skarels struct sockaddr_in *dst; 15427231Skarels { 15528906Skarels register u_long r = 15628906Skarels ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); 15727231Skarels register u_long d = ntohl(dst->sin_addr.s_addr); 15827231Skarels 15928906Skarels if (IN_CLASSA(r)) { 16028906Skarels if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) { 16128906Skarels if ((r & IN_CLASSA_HOST) == 0) 16228906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 16327231Skarels return (1); 16428906Skarels } 165*28994Skarels if (r & IN_CLASSA_HOST) 166*28994Skarels return (0); 167*28994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 16828906Skarels } else if (IN_CLASSB(r)) { 16928906Skarels if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) { 17028906Skarels if ((r & IN_CLASSB_HOST) == 0) 17128906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 17227231Skarels return (1); 17328906Skarels } 174*28994Skarels if (r & IN_CLASSB_HOST) 175*28994Skarels return (0); 176*28994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 17727231Skarels } else { 17828906Skarels if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) { 17928906Skarels if ((r & IN_CLASSC_HOST) == 0) 18028906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 18127231Skarels return (1); 18228906Skarels } 183*28994Skarels if (r & IN_CLASSC_HOST) 184*28994Skarels return (0); 185*28994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 18627231Skarels } 18727231Skarels } 188