121994Sdist /* 2*61540Sbostic * Copyright (c) 1983, 1993 3*61540Sbostic * The Regents of the University of California. All rights reserved. 433489Sbostic * 542712Sbostic * %sccs.include.redist.c% 621994Sdist */ 721994Sdist 816395Skarels #ifndef lint 9*61540Sbostic static char sccsid[] = "@(#)inet.c 8.1 (Berkeley) 06/05/93"; 1033489Sbostic #endif /* not lint */ 1121994Sdist 1216395Skarels /* 1316395Skarels * Temporarily, copy these routines from the kernel, 1416395Skarels * as we need to know about subnets. 1516395Skarels */ 1616395Skarels #include "defs.h" 1716395Skarels 1821846Skarels extern struct interface *ifnet; 1921846Skarels 2016395Skarels /* 2121846Skarels * Formulate an Internet address from network + host. 2216395Skarels */ 2316395Skarels struct in_addr 2421846Skarels inet_makeaddr(net, host) 2521846Skarels u_long net, host; 2616395Skarels { 2721846Skarels register struct interface *ifp; 2821846Skarels register u_long mask; 2916395Skarels u_long addr; 3016395Skarels 3121846Skarels if (IN_CLASSA(net)) 3221846Skarels mask = IN_CLASSA_HOST; 3321846Skarels else if (IN_CLASSB(net)) 3421846Skarels mask = IN_CLASSB_HOST; 3516395Skarels else 3621846Skarels mask = IN_CLASSC_HOST; 3721846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 3821846Skarels if ((ifp->int_netmask & net) == ifp->int_net) { 3921846Skarels mask = ~ifp->int_subnetmask; 4021846Skarels break; 4121846Skarels } 4221846Skarels addr = net | (host & mask); 4316395Skarels addr = htonl(addr); 4416395Skarels return (*(struct in_addr *)&addr); 4516395Skarels } 4616395Skarels 4716395Skarels /* 4816395Skarels * Return the network number from an internet address. 4916395Skarels */ 5016395Skarels inet_netof(in) 5116395Skarels struct in_addr in; 5216395Skarels { 5316395Skarels register u_long i = ntohl(in.s_addr); 5421846Skarels register u_long net; 5516429Skarels register struct interface *ifp; 5616395Skarels 5721846Skarels if (IN_CLASSA(i)) 5821846Skarels net = i & IN_CLASSA_NET; 5921846Skarels else if (IN_CLASSB(i)) 6021846Skarels net = i & IN_CLASSB_NET; 6121846Skarels else 6221846Skarels net = i & IN_CLASSC_NET; 6316429Skarels 6416429Skarels /* 6521846Skarels * Check whether network is a subnet; 6616429Skarels * if so, return subnet number. 6716429Skarels */ 6821846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 6921846Skarels if ((ifp->int_netmask & net) == ifp->int_net) 7021846Skarels return (i & ifp->int_subnetmask); 7116429Skarels return (net); 7216395Skarels } 7316395Skarels 7416395Skarels /* 7516395Skarels * Return the host portion of an internet address. 7616395Skarels */ 7716395Skarels inet_lnaof(in) 7816395Skarels struct in_addr in; 7916395Skarels { 8016395Skarels register u_long i = ntohl(in.s_addr); 8121846Skarels register u_long net, host; 8216429Skarels register struct interface *ifp; 8316395Skarels 8416395Skarels if (IN_CLASSA(i)) { 8521846Skarels net = i & IN_CLASSA_NET; 8621846Skarels host = i & IN_CLASSA_HOST; 8716395Skarels } else if (IN_CLASSB(i)) { 8821846Skarels net = i & IN_CLASSB_NET; 8921846Skarels host = i & IN_CLASSB_HOST; 9016395Skarels } else { 9121846Skarels net = i & IN_CLASSC_NET; 9221846Skarels host = i & IN_CLASSC_HOST; 9316395Skarels } 9416395Skarels 9516429Skarels /* 9621846Skarels * Check whether network is a subnet; 9716429Skarels * if so, use the modified interpretation of `host'. 9816429Skarels */ 9921846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 10021846Skarels if ((ifp->int_netmask & net) == ifp->int_net) 10121846Skarels return (host &~ ifp->int_subnetmask); 10216429Skarels return (host); 10316395Skarels } 10427231Skarels 10527231Skarels /* 10652583Ssklower * Return the netmask pertaining to an internet address. 10752583Ssklower */ 10852583Ssklower inet_maskof(in) 10952583Ssklower struct in_addr in; 11052583Ssklower { 11152583Ssklower register u_long i = ntohl(in.s_addr); 11252583Ssklower register u_long mask; 11352583Ssklower register struct interface *ifp; 11452583Ssklower 11552910Ssklower if (i == 0) { 11652910Ssklower mask = 0; 11752910Ssklower } else if (IN_CLASSA(i)) { 11852583Ssklower mask = IN_CLASSA_NET; 11952583Ssklower } else if (IN_CLASSB(i)) { 12052583Ssklower mask = i & IN_CLASSB_NET; 12152583Ssklower } else 12252583Ssklower mask = i & IN_CLASSC_NET; 12352583Ssklower 12452583Ssklower /* 12552583Ssklower * Check whether network is a subnet; 12652583Ssklower * if so, use the modified interpretation of `host'. 12752583Ssklower */ 12852583Ssklower for (ifp = ifnet; ifp; ifp = ifp->int_next) 12952583Ssklower if ((ifp->int_netmask & i) == ifp->int_net) 13052583Ssklower mask = ifp->int_subnetmask; 13152583Ssklower return (htonl(mask)); 13252583Ssklower } 13352583Ssklower 13452583Ssklower /* 13527231Skarels * Return RTF_HOST if the address is 13627231Skarels * for an Internet host, RTF_SUBNET for a subnet, 13727231Skarels * 0 for a network. 13827231Skarels */ 13927231Skarels inet_rtflags(sin) 14027231Skarels struct sockaddr_in *sin; 14127231Skarels { 14227231Skarels register u_long i = ntohl(sin->sin_addr.s_addr); 14327231Skarels register u_long net, host; 14427231Skarels register struct interface *ifp; 14527231Skarels 14627231Skarels if (IN_CLASSA(i)) { 14727231Skarels net = i & IN_CLASSA_NET; 14827231Skarels host = i & IN_CLASSA_HOST; 14927231Skarels } else if (IN_CLASSB(i)) { 15027231Skarels net = i & IN_CLASSB_NET; 15127231Skarels host = i & IN_CLASSB_HOST; 15227231Skarels } else { 15327231Skarels net = i & IN_CLASSC_NET; 15427231Skarels host = i & IN_CLASSC_HOST; 15527231Skarels } 15627231Skarels 15727231Skarels /* 15827231Skarels * Check whether this network is subnetted; 15927231Skarels * if so, check whether this is a subnet or a host. 16027231Skarels */ 16127231Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 16227231Skarels if (net == ifp->int_net) { 16328994Skarels if (host &~ ifp->int_subnetmask) 16428994Skarels return (RTF_HOST); 16528994Skarels else if (ifp->int_subnetmask != ifp->int_netmask) 16627231Skarels return (RTF_SUBNET); 16727231Skarels else 16828994Skarels return (0); /* network */ 16927231Skarels } 17028994Skarels if (host == 0) 17128994Skarels return (0); /* network */ 17228994Skarels else 17328994Skarels return (RTF_HOST); 17427231Skarels } 17527231Skarels 17627231Skarels /* 17731220Skarels * Return true if a route to subnet/host of route rt should be sent to dst. 17831220Skarels * Send it only if dst is on the same logical network if not "internal", 17931220Skarels * otherwise only if the route is the "internal" route for the logical net. 18027231Skarels */ 18131220Skarels inet_sendroute(rt, dst) 18228906Skarels struct rt_entry *rt; 18328906Skarels struct sockaddr_in *dst; 18427231Skarels { 18528906Skarels register u_long r = 18628906Skarels ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); 18727231Skarels register u_long d = ntohl(dst->sin_addr.s_addr); 18827231Skarels 18928906Skarels if (IN_CLASSA(r)) { 19028906Skarels if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) { 19128906Skarels if ((r & IN_CLASSA_HOST) == 0) 19228906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 19327231Skarels return (1); 19428906Skarels } 19528994Skarels if (r & IN_CLASSA_HOST) 19628994Skarels return (0); 19728994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 19828906Skarels } else if (IN_CLASSB(r)) { 19928906Skarels if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) { 20028906Skarels if ((r & IN_CLASSB_HOST) == 0) 20128906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 20227231Skarels return (1); 20328906Skarels } 20428994Skarels if (r & IN_CLASSB_HOST) 20528994Skarels return (0); 20628994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 20727231Skarels } else { 20828906Skarels if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) { 20928906Skarels if ((r & IN_CLASSC_HOST) == 0) 21028906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 21127231Skarels return (1); 21228906Skarels } 21328994Skarels if (r & IN_CLASSC_HOST) 21428994Skarels return (0); 21528994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 21627231Skarels } 21727231Skarels } 218