121994Sdist /*
261540Sbostic * Copyright (c) 1983, 1993
361540Sbostic * The Regents of the University of California. All rights reserved.
433489Sbostic *
542712Sbostic * %sccs.include.redist.c%
621994Sdist */
721994Sdist
816395Skarels #ifndef lint
9*68111Ssklower static char sccsid[] = "@(#)inet.c 8.3 (Berkeley) 12/30/94";
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
inet_makeaddr(net,host)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 */
inet_maskof(inaddr)10864253Smckusick inet_maskof(inaddr)
10964253Smckusick u_long inaddr;
11052583Ssklower {
11164253Smckusick register u_long i = ntohl(inaddr);
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)) {
120*68111Ssklower mask = IN_CLASSB_NET;
12152583Ssklower } else
122*68111Ssklower mask = 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