121994Sdist /* 221994Sdist * Copyright (c) 1983 Regents of the University of California. 333489Sbostic * All rights reserved. 433489Sbostic * 542712Sbostic * %sccs.include.redist.c% 621994Sdist */ 721994Sdist 816395Skarels #ifndef lint 9*52583Ssklower static char sccsid[] = "@(#)inet.c 5.9 (Berkeley) 02/19/92"; 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 /* 106*52583Ssklower * Return the netmask pertaining to an internet address. 107*52583Ssklower */ 108*52583Ssklower inet_maskof(in) 109*52583Ssklower struct in_addr in; 110*52583Ssklower { 111*52583Ssklower register u_long i = ntohl(in.s_addr); 112*52583Ssklower register u_long mask; 113*52583Ssklower register struct interface *ifp; 114*52583Ssklower 115*52583Ssklower if (IN_CLASSA(i)) { 116*52583Ssklower mask = IN_CLASSA_NET; 117*52583Ssklower } else if (IN_CLASSB(i)) { 118*52583Ssklower mask = i & IN_CLASSB_NET; 119*52583Ssklower } else 120*52583Ssklower mask = i & IN_CLASSC_NET; 121*52583Ssklower 122*52583Ssklower /* 123*52583Ssklower * Check whether network is a subnet; 124*52583Ssklower * if so, use the modified interpretation of `host'. 125*52583Ssklower */ 126*52583Ssklower for (ifp = ifnet; ifp; ifp = ifp->int_next) 127*52583Ssklower if ((ifp->int_netmask & i) == ifp->int_net) 128*52583Ssklower mask = ifp->int_subnetmask; 129*52583Ssklower return (htonl(mask)); 130*52583Ssklower } 131*52583Ssklower 132*52583Ssklower /* 13327231Skarels * Return RTF_HOST if the address is 13427231Skarels * for an Internet host, RTF_SUBNET for a subnet, 13527231Skarels * 0 for a network. 13627231Skarels */ 13727231Skarels inet_rtflags(sin) 13827231Skarels struct sockaddr_in *sin; 13927231Skarels { 14027231Skarels register u_long i = ntohl(sin->sin_addr.s_addr); 14127231Skarels register u_long net, host; 14227231Skarels register struct interface *ifp; 14327231Skarels 14427231Skarels if (IN_CLASSA(i)) { 14527231Skarels net = i & IN_CLASSA_NET; 14627231Skarels host = i & IN_CLASSA_HOST; 14727231Skarels } else if (IN_CLASSB(i)) { 14827231Skarels net = i & IN_CLASSB_NET; 14927231Skarels host = i & IN_CLASSB_HOST; 15027231Skarels } else { 15127231Skarels net = i & IN_CLASSC_NET; 15227231Skarels host = i & IN_CLASSC_HOST; 15327231Skarels } 15427231Skarels 15527231Skarels /* 15627231Skarels * Check whether this network is subnetted; 15727231Skarels * if so, check whether this is a subnet or a host. 15827231Skarels */ 15927231Skarels for (ifp = ifnet; ifp; ifp = ifp->int_next) 16027231Skarels if (net == ifp->int_net) { 16128994Skarels if (host &~ ifp->int_subnetmask) 16228994Skarels return (RTF_HOST); 16328994Skarels else if (ifp->int_subnetmask != ifp->int_netmask) 16427231Skarels return (RTF_SUBNET); 16527231Skarels else 16628994Skarels return (0); /* network */ 16727231Skarels } 16828994Skarels if (host == 0) 16928994Skarels return (0); /* network */ 17028994Skarels else 17128994Skarels return (RTF_HOST); 17227231Skarels } 17327231Skarels 17427231Skarels /* 17531220Skarels * Return true if a route to subnet/host of route rt should be sent to dst. 17631220Skarels * Send it only if dst is on the same logical network if not "internal", 17731220Skarels * otherwise only if the route is the "internal" route for the logical net. 17827231Skarels */ 17931220Skarels inet_sendroute(rt, dst) 18028906Skarels struct rt_entry *rt; 18128906Skarels struct sockaddr_in *dst; 18227231Skarels { 18328906Skarels register u_long r = 18428906Skarels ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); 18527231Skarels register u_long d = ntohl(dst->sin_addr.s_addr); 18627231Skarels 18728906Skarels if (IN_CLASSA(r)) { 18828906Skarels if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) { 18928906Skarels if ((r & IN_CLASSA_HOST) == 0) 19028906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 19127231Skarels return (1); 19228906Skarels } 19328994Skarels if (r & IN_CLASSA_HOST) 19428994Skarels return (0); 19528994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 19628906Skarels } else if (IN_CLASSB(r)) { 19728906Skarels if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) { 19828906Skarels if ((r & IN_CLASSB_HOST) == 0) 19928906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 20027231Skarels return (1); 20128906Skarels } 20228994Skarels if (r & IN_CLASSB_HOST) 20328994Skarels return (0); 20428994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 20527231Skarels } else { 20628906Skarels if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) { 20728906Skarels if ((r & IN_CLASSC_HOST) == 0) 20828906Skarels return ((rt->rt_state & RTS_INTERNAL) == 0); 20927231Skarels return (1); 21028906Skarels } 21128994Skarels if (r & IN_CLASSC_HOST) 21228994Skarels return (0); 21328994Skarels return ((rt->rt_state & RTS_INTERNAL) != 0); 21427231Skarels } 21527231Skarels } 216