121994Sdist /* 221994Sdist * Copyright (c) 1983 Regents of the University of California. 3*33489Sbostic * All rights reserved. 4*33489Sbostic * 5*33489Sbostic * Redistribution and use in source and binary forms are permitted 6*33489Sbostic * provided that this notice is preserved and that due credit is given 7*33489Sbostic * to the University of California at Berkeley. The name of the University 8*33489Sbostic * may not be used to endorse or promote products derived from this 9*33489Sbostic * software without specific prior written permission. This software 10*33489Sbostic * is provided ``as is'' without express or implied warranty. 1121994Sdist */ 1221994Sdist 1316395Skarels #ifndef lint 14*33489Sbostic static char sccsid[] = "@(#)inet.c 5.6 (Berkeley) 02/16/88"; 15*33489Sbostic #endif /* not lint */ 1621994Sdist 1716395Skarels /* 1816395Skarels * Temporarily, copy these routines from the kernel, 1916395Skarels * as we need to know about subnets. 2016395Skarels */ 2116395Skarels #include "defs.h" 2216395Skarels 2321846Skarels extern struct interface *ifnet; 2421846Skarels 2516395Skarels /* 2621846Skarels * Formulate an Internet address from network + host. 2716395Skarels */ 2816395Skarels struct in_addr 2921846Skarels inet_makeaddr(net, host) 3021846Skarels u_long net, host; 3116395Skarels { 3221846Skarels register struct interface *ifp; 3321846Skarels register u_long mask; 3416395Skarels u_long addr; 3516395Skarels 3621846Skarels if (IN_CLASSA(net)) 3721846Skarels mask = IN_CLASSA_HOST; 3821846Skarels else if (IN_CLASSB(net)) 3921846Skarels mask = IN_CLASSB_HOST; 4016395Skarels else 4121846Skarels mask = IN_CLASSC_HOST; 4221846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 4321846Skarels if ((ifp->int_netmask & net) == ifp->int_net) { 4421846Skarels mask = ~ifp->int_subnetmask; 4521846Skarels break; 4621846Skarels } 4721846Skarels addr = net | (host & mask); 4816395Skarels addr = htonl(addr); 4916395Skarels return (*(struct in_addr *)&addr); 5016395Skarels } 5116395Skarels 5216395Skarels /* 5316395Skarels * Return the network number from an internet address. 5416395Skarels */ 5516395Skarels inet_netof(in) 5616395Skarels struct in_addr in; 5716395Skarels { 5816395Skarels register u_long i = ntohl(in.s_addr); 5921846Skarels register u_long net; 6016429Skarels register struct interface *ifp; 6116395Skarels 6221846Skarels if (IN_CLASSA(i)) 6321846Skarels net = i & IN_CLASSA_NET; 6421846Skarels else if (IN_CLASSB(i)) 6521846Skarels net = i & IN_CLASSB_NET; 6621846Skarels else 6721846Skarels net = i & IN_CLASSC_NET; 6816429Skarels 6916429Skarels /* 7021846Skarels * Check whether network is a subnet; 7116429Skarels * if so, return subnet number. 7216429Skarels */ 7321846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 7421846Skarels if ((ifp->int_netmask & net) == ifp->int_net) 7521846Skarels return (i & ifp->int_subnetmask); 7616429Skarels return (net); 7716395Skarels } 7816395Skarels 7916395Skarels /* 8016395Skarels * Return the host portion of an internet address. 8116395Skarels */ 8216395Skarels inet_lnaof(in) 8316395Skarels struct in_addr in; 8416395Skarels { 8516395Skarels register u_long i = ntohl(in.s_addr); 8621846Skarels register u_long net, host; 8716429Skarels register struct interface *ifp; 8816395Skarels 8916395Skarels if (IN_CLASSA(i)) { 9021846Skarels net = i & IN_CLASSA_NET; 9121846Skarels host = i & IN_CLASSA_HOST; 9216395Skarels } else if (IN_CLASSB(i)) { 9321846Skarels net = i & IN_CLASSB_NET; 9421846Skarels host = i & IN_CLASSB_HOST; 9516395Skarels } else { 9621846Skarels net = i & IN_CLASSC_NET; 9721846Skarels host = i & IN_CLASSC_HOST; 9816395Skarels } 9916395Skarels 10016429Skarels /* 10121846Skarels * Check whether network is a subnet; 10216429Skarels * if so, use the modified interpretation of `host'. 10316429Skarels */ 10421846Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 10521846Skarels if ((ifp->int_netmask & net) == ifp->int_net) 10621846Skarels return (host &~ ifp->int_subnetmask); 10716429Skarels return (host); 10816395Skarels } 10927231Skarels 11027231Skarels /* 11127231Skarels * Return RTF_HOST if the address is 11227231Skarels * for an Internet host, RTF_SUBNET for a subnet, 11327231Skarels * 0 for a network. 11427231Skarels */ 11527231Skarels inet_rtflags(sin) 11627231Skarels struct sockaddr_in *sin; 11727231Skarels { 11827231Skarels register u_long i = ntohl(sin->sin_addr.s_addr); 11927231Skarels register u_long net, host; 12027231Skarels register struct interface *ifp; 12127231Skarels 12227231Skarels if (IN_CLASSA(i)) { 12327231Skarels net = i & IN_CLASSA_NET; 12427231Skarels host = i & IN_CLASSA_HOST; 12527231Skarels } else if (IN_CLASSB(i)) { 12627231Skarels net = i & IN_CLASSB_NET; 12727231Skarels host = i & IN_CLASSB_HOST; 12827231Skarels } else { 12927231Skarels net = i & IN_CLASSC_NET; 13027231Skarels host = i & IN_CLASSC_HOST; 13127231Skarels } 13227231Skarels 13327231Skarels /* 13427231Skarels * Check whether this network is subnetted; 13527231Skarels * if so, check whether this is a subnet or a host. 13627231Skarels */ 13727231Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 13827231Skarels if (net == ifp->int_net) { 13928994Skarels if (host &~ ifp->int_subnetmask) 14028994Skarels return (RTF_HOST); 14128994Skarels else if (ifp->int_subnetmask != ifp->int_netmask) 14227231Skarels return (RTF_SUBNET); 14327231Skarels else 14428994Skarels return (0); /* network */ 14527231Skarels } 14628994Skarels if (host == 0) 14728994Skarels return (0); /* network */ 14828994Skarels else 14928994Skarels return (RTF_HOST); 15027231Skarels } 15127231Skarels 15227231Skarels /* 15331220Skarels * Return true if a route to subnet/host of route rt should be sent to dst. 15431220Skarels * Send it only if dst is on the same logical network if not "internal", 15531220Skarels * otherwise only if the route is the "internal" route for the logical net. 15627231Skarels */ 15731220Skarels inet_sendroute(rt, dst) 15828906Skarels struct rt_entry *rt; 15928906Skarels struct sockaddr_in *dst; 16027231Skarels { 16128906Skarels register u_long r = 16228906Skarels ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); 16327231Skarels register u_long d = ntohl(dst->sin_addr.s_addr); 16427231Skarels 16528906Skarels if (IN_CLASSA(r)) { 16628906Skarels if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) { 16728906Skarels if ((r & IN_CLASSA_HOST) == 0) 16828906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 16927231Skarels return (1); 17028906Skarels } 17128994Skarels if (r & IN_CLASSA_HOST) 17228994Skarels return (0); 17328994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 17428906Skarels } else if (IN_CLASSB(r)) { 17528906Skarels if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) { 17628906Skarels if ((r & IN_CLASSB_HOST) == 0) 17728906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 17827231Skarels return (1); 17928906Skarels } 18028994Skarels if (r & IN_CLASSB_HOST) 18128994Skarels return (0); 18228994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 18327231Skarels } else { 18428906Skarels if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) { 18528906Skarels if ((r & IN_CLASSC_HOST) == 0) 18628906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 18727231Skarels return (1); 18828906Skarels } 18928994Skarels if (r & IN_CLASSC_HOST) 19028994Skarels return (0); 19128994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 19227231Skarels } 19327231Skarels } 194