xref: /csrg-svn/sbin/routed/startup.c (revision 69003)
121998Sdist /*
261540Sbostic  * Copyright (c) 1983, 1988, 1993
361540Sbostic  *	The Regents of the University of California.  All rights reserved.
433489Sbostic  *
542712Sbostic  * %sccs.include.redist.c%
621998Sdist  */
721998Sdist 
89019Ssam #ifndef lint
9*69003Sbostic static char sccsid[] = "@(#)startup.c	8.2 (Berkeley) 04/28/95";
1033489Sbostic #endif /* not lint */
119019Ssam 
129019Ssam /*
139019Ssam  * Routing Table Management Daemon
149019Ssam  */
1510245Ssam #include "defs.h"
1616327Skarels #include <sys/ioctl.h>
1758927Smckusick #include <sys/sysctl.h>
189019Ssam #include <net/if.h>
1952583Ssklower #include <net/if_dl.h>
2017571Skarels #include <syslog.h>
2146784Sbostic #include <stdlib.h>
2237292Sbostic #include "pathnames.h"
239019Ssam 
249019Ssam struct	interface *ifnet;
2536831Skarels struct	interface **ifnext = &ifnet;
269019Ssam int	lookforinterfaces = 1;
279019Ssam int	externalinterfaces = 0;		/* # of remote and local interfaces */
2831220Skarels int	foundloopback;			/* valid flag for loopaddr */
2931220Skarels struct	sockaddr loopaddr;		/* our address on loopback */
309019Ssam 
3152583Ssklower 
3252583Ssklower void
quit(s)3352583Ssklower quit(s)
3452583Ssklower 	char *s;
3552583Ssklower {
3652583Ssklower 	extern int errno;
3752583Ssklower 	int sverrno = errno;
3852583Ssklower 
3952583Ssklower 	(void) fprintf(stderr, "route: ");
4052583Ssklower 	if (s)
4152583Ssklower 		(void) fprintf(stderr, "%s: ", s);
4252583Ssklower 	(void) fprintf(stderr, "%s\n", strerror(sverrno));
4352583Ssklower 	exit(1);
4452583Ssklower 	/* NOTREACHED */
4552583Ssklower }
4652583Ssklower 
4752583Ssklower struct rt_addrinfo info;
4852583Ssklower /* Sleazy use of local variables throughout file, warning!!!! */
4952583Ssklower #define netmask	info.rti_info[RTAX_NETMASK]
5052583Ssklower #define ifaaddr	info.rti_info[RTAX_IFA]
5152583Ssklower #define brdaddr	info.rti_info[RTAX_BRD]
5252583Ssklower 
5352583Ssklower #define ROUNDUP(a) \
5452583Ssklower 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
5552583Ssklower #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
5652583Ssklower 
5752583Ssklower void
rt_xaddrs(cp,cplim,rtinfo)5852583Ssklower rt_xaddrs(cp, cplim, rtinfo)
5952583Ssklower 	register caddr_t cp, cplim;
6052583Ssklower 	register struct rt_addrinfo *rtinfo;
6152583Ssklower {
6252583Ssklower 	register struct sockaddr *sa;
6352583Ssklower 	register int i;
6452583Ssklower 
65*69003Sbostic 	memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
6652583Ssklower 	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
6752583Ssklower 		if ((rtinfo->rti_addrs & (1 << i)) == 0)
6852583Ssklower 			continue;
6952583Ssklower 		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
7052583Ssklower 		ADVANCE(cp, sa);
7152583Ssklower 	}
7252583Ssklower }
7352583Ssklower 
749019Ssam /*
7521842Skarels  * Find the network interfaces which have configured themselves.
7621842Skarels  * If the interface is present but not yet up (for example an
779019Ssam  * ARPANET IMP), set the lookforinterfaces flag so we'll
789019Ssam  * come back later and look again.
799019Ssam  */
ifinit()809019Ssam ifinit()
819019Ssam {
8221842Skarels 	struct interface ifs, *ifp;
8358927Smckusick 	size_t needed;
8458927Smckusick 	int mib[6], no_ipaddr = 0, flags = 0;
8552583Ssklower 	char *buf, *cplim, *cp;
8652583Ssklower 	register struct if_msghdr *ifm;
8752583Ssklower 	register struct ifa_msghdr *ifam;
8852583Ssklower 	struct sockaddr_dl *sdl;
8921842Skarels         struct sockaddr_in *sin;
9021842Skarels 	u_long i;
919019Ssam 
9258927Smckusick         mib[0] = CTL_NET;
9358927Smckusick         mib[1] = PF_ROUTE;
9458927Smckusick         mib[2] = 0;
9558927Smckusick         mib[3] = AF_INET;
9658927Smckusick         mib[4] = NET_RT_IFLIST;
9758927Smckusick         mib[5] = 0;
9858927Smckusick         if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
9958927Smckusick                 quit("route-sysctl-estimate");
10052583Ssklower 	if ((buf = malloc(needed)) == NULL)
10152583Ssklower 		quit("malloc");
10258927Smckusick         if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
10352583Ssklower 		quit("actual retrieval of interface table");
1049019Ssam 	lookforinterfaces = 0;
10558927Smckusick 	cplim = buf + needed;
10652583Ssklower 	for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) {
10752583Ssklower 		ifm = (struct if_msghdr *)cp;
10852583Ssklower 		if (ifm->ifm_type == RTM_IFINFO) {
109*69003Sbostic 			memset(&ifs, 0, sizeof(ifs));
11055904Ssklower 			ifs.int_flags = flags = (0xffff & ifm->ifm_flags) | IFF_INTERFACE;
11152583Ssklower 			if ((flags & IFF_UP) == 0 || no_ipaddr)
11252583Ssklower 				lookforinterfaces = 1;
11352583Ssklower 			sdl = (struct sockaddr_dl *) (ifm + 1);
11452583Ssklower 			sdl->sdl_data[sdl->sdl_nlen] = 0;
11552583Ssklower 			no_ipaddr = 1;
1169019Ssam 			continue;
1179019Ssam 		}
11852583Ssklower 		if (ifm->ifm_type != RTM_NEWADDR)
11952583Ssklower 			quit("ifinit: out of sync");
12052583Ssklower 		if ((flags & IFF_UP) == 0)
12152583Ssklower 			continue;
12252583Ssklower 		ifam = (struct ifa_msghdr *)ifm;
12352583Ssklower 		info.rti_addrs = ifam->ifam_addrs;
12452583Ssklower 		rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info);
12552583Ssklower 		if (ifaaddr == 0) {
12652583Ssklower 			syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data);
12752583Ssklower 			continue;
12852583Ssklower 		}
12952583Ssklower 		ifs.int_addr = *ifaaddr;
13036831Skarels 		if (ifs.int_addr.sa_family != AF_INET)
13136831Skarels 			continue;
13252583Ssklower 		no_ipaddr = 0;
13352583Ssklower 		if (ifs.int_flags & IFF_POINTOPOINT) {
13452583Ssklower 			if (brdaddr == 0) {
13552583Ssklower 				syslog(LOG_ERR, "%s: (get dstaddr)",
13652583Ssklower 					sdl->sdl_data);
13752583Ssklower 				continue;
13836831Skarels 			}
13952583Ssklower 			if (brdaddr->sa_family == AF_UNSPEC) {
14036831Skarels 				lookforinterfaces = 1;
14136831Skarels 				continue;
14236831Skarels 			}
14352583Ssklower 			ifs.int_dstaddr = *brdaddr;
14436831Skarels 		}
14534568Skarels 		/*
14634568Skarels 		 * already known to us?
14734568Skarels 		 * This allows multiple point-to-point links
14834568Skarels 		 * to share a source address (possibly with one
14934568Skarels 		 * other link), but assumes that there will not be
15034568Skarels 		 * multiple links with the same destination address.
15134568Skarels 		 */
15234568Skarels 		if (ifs.int_flags & IFF_POINTOPOINT) {
15334568Skarels 			if (if_ifwithdstaddr(&ifs.int_dstaddr))
15434568Skarels 				continue;
15534568Skarels 		} else if (if_ifwithaddr(&ifs.int_addr))
1569019Ssam 			continue;
15731220Skarels 		if (ifs.int_flags & IFF_LOOPBACK) {
15834568Skarels 			ifs.int_flags |= IFF_PASSIVE;
15931220Skarels 			foundloopback = 1;
16031220Skarels 			loopaddr = ifs.int_addr;
16131220Skarels 			for (ifp = ifnet; ifp; ifp = ifp->int_next)
16231220Skarels 			    if (ifp->int_flags & IFF_POINTOPOINT)
16331220Skarels 				add_ptopt_localrt(ifp);
16431220Skarels 		}
16552583Ssklower 		if (ifs.int_flags & IFF_BROADCAST) {
16652583Ssklower 			if (brdaddr == 0) {
16752583Ssklower 				syslog(LOG_ERR, "%s: (get broadaddr)",
16852583Ssklower 					sdl->sdl_data);
16952583Ssklower 				continue;
17052583Ssklower 			}
17152583Ssklower 			ifs.int_dstaddr = *brdaddr;
17221842Skarels 		}
17352621Ssklower 		/*
17452621Ssklower 		 * Use a minimum metric of one;
17552621Ssklower 		 * treat the interface metric (default 0)
17652621Ssklower 		 * as an increment to the hop count of one.
17752621Ssklower 		 */
17852621Ssklower 		ifs.int_metric = ifam->ifam_metric + 1;
17952583Ssklower 		if (netmask == 0) {
18052583Ssklower 				syslog(LOG_ERR, "%s: (get netmask)",
18152583Ssklower 					sdl->sdl_data);
18252583Ssklower 				continue;
18321842Skarels 		}
18452583Ssklower 		sin = (struct sockaddr_in *)netmask;
18521842Skarels 		ifs.int_subnetmask = ntohl(sin->sin_addr.s_addr);
18621842Skarels 		sin = (struct sockaddr_in *)&ifs.int_addr;
18721842Skarels 		i = ntohl(sin->sin_addr.s_addr);
18821842Skarels 		if (IN_CLASSA(i))
18921842Skarels 			ifs.int_netmask = IN_CLASSA_NET;
19021842Skarels 		else if (IN_CLASSB(i))
19121842Skarels 			ifs.int_netmask = IN_CLASSB_NET;
19221842Skarels 		else
19321842Skarels 			ifs.int_netmask = IN_CLASSC_NET;
19421842Skarels 		ifs.int_net = i & ifs.int_netmask;
19521842Skarels 		ifs.int_subnet = i & ifs.int_subnetmask;
19627231Skarels 		if (ifs.int_subnetmask != ifs.int_netmask)
19727231Skarels 			ifs.int_flags |= IFF_SUBNET;
19852583Ssklower 		ifp = (struct interface *)
19952583Ssklower 			malloc(sdl->sdl_nlen + 1 + sizeof(ifs));
2009019Ssam 		if (ifp == 0) {
2019019Ssam 			printf("routed: out of memory\n");
20252583Ssklower 			lookforinterfaces = 1;
2039019Ssam 			break;
2049019Ssam 		}
20521842Skarels 		*ifp = ifs;
2069019Ssam 		/*
2079019Ssam 		 * Count the # of directly connected networks
2089019Ssam 		 * and point to point links which aren't looped
2099019Ssam 		 * back to ourself.  This is used below to
2109019Ssam 		 * decide if we should be a routing ``supplier''.
2119019Ssam 		 */
21231220Skarels 		if ((ifs.int_flags & IFF_LOOPBACK) == 0 &&
21331220Skarels 		    ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
21431220Skarels 		    if_ifwithaddr(&ifs.int_dstaddr) == 0))
2159019Ssam 			externalinterfaces++;
21625505Skarels 		/*
21725505Skarels 		 * If we have a point-to-point link, we want to act
21825505Skarels 		 * as a supplier even if it's our only interface,
21925505Skarels 		 * as that's the only way our peer on the other end
22025505Skarels 		 * can tell that the link is up.
22125505Skarels 		 */
22225505Skarels 		if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
22325505Skarels 			supplier = 1;
22452583Ssklower 		ifp->int_name = (char *)(ifp + 1);
22552583Ssklower 		strcpy(ifp->int_name, sdl->sdl_data);
22636831Skarels 		*ifnext = ifp;
22736831Skarels 		ifnext = &ifp->int_next;
2289019Ssam 		traceinit(ifp);
2299019Ssam 		addrouteforif(ifp);
2309019Ssam 	}
2319019Ssam 	if (externalinterfaces > 1 && supplier < 0)
2329019Ssam 		supplier = 1;
23352583Ssklower 	free(buf);
2349019Ssam }
2359019Ssam 
23627231Skarels /*
23727231Skarels  * Add route for interface if not currently installed.
23827231Skarels  * Create route to other end if a point-to-point link,
23927231Skarels  * otherwise a route to this (sub)network.
24027231Skarels  * INTERNET SPECIFIC.
24127231Skarels  */
addrouteforif(ifp)2429019Ssam addrouteforif(ifp)
24331220Skarels 	register struct interface *ifp;
2449019Ssam {
2459019Ssam 	struct sockaddr_in net;
2469019Ssam 	struct sockaddr *dst;
24734661Skarels 	int state;
24831220Skarels 	register struct rt_entry *rt;
2499019Ssam 
2509019Ssam 	if (ifp->int_flags & IFF_POINTOPOINT)
2519019Ssam 		dst = &ifp->int_dstaddr;
2529019Ssam 	else {
253*69003Sbostic 		memset(&net, 0, sizeof (net));
2549019Ssam 		net.sin_family = AF_INET;
25521842Skarels 		net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY);
2569019Ssam 		dst = (struct sockaddr *)&net;
2579019Ssam 	}
25821842Skarels 	rt = rtfind(dst);
25929002Skarels 	if (rt &&
26029002Skarels 	    (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE)
26118114Skarels 		return;
26221842Skarels 	if (rt)
26321842Skarels 		rtdelete(rt);
26427231Skarels 	/*
26527231Skarels 	 * If interface on subnetted network,
26627231Skarels 	 * install route to network as well.
26727231Skarels 	 * This is meant for external viewers.
26827231Skarels 	 */
26927231Skarels 	if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) {
27031220Skarels 		struct in_addr subnet;
27131220Skarels 
27231220Skarels 		subnet = net.sin_addr;
27327231Skarels 		net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
27427231Skarels 		rt = rtfind(dst);
27529002Skarels 		if (rt == 0)
27629002Skarels 			rtadd(dst, &ifp->int_addr, ifp->int_metric,
27729002Skarels 			    ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) |
27831220Skarels 			    RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET));
27931220Skarels 		else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) ==
28031220Skarels 		    (RTS_INTERNAL|RTS_SUBNET) &&
28131220Skarels 		    ifp->int_metric < rt->rt_metric)
28231220Skarels 			rtchange(rt, &rt->rt_router, ifp->int_metric);
28331220Skarels 		net.sin_addr = subnet;
28427231Skarels 	}
28529002Skarels 	if (ifp->int_transitions++ > 0)
28629002Skarels 		syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
28731220Skarels 	state = ifp->int_flags &
28831220Skarels 	    (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET);
28931220Skarels 	if (ifp->int_flags & IFF_POINTOPOINT &&
29031220Skarels 	    (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) &
29131220Skarels 	    ifp->int_netmask) != ifp->int_net)
29231220Skarels 		state &= ~RTS_SUBNET;
29331220Skarels 	if (ifp->int_flags & IFF_LOOPBACK)
29434568Skarels 		state |= RTS_EXTERNAL;
29531220Skarels 	rtadd(dst, &ifp->int_addr, ifp->int_metric, state);
29631220Skarels 	if (ifp->int_flags & IFF_POINTOPOINT && foundloopback)
29731220Skarels 		add_ptopt_localrt(ifp);
29831220Skarels }
29929002Skarels 
30031220Skarels /*
30131220Skarels  * Add route to local end of point-to-point using loopback.
30231220Skarels  * If a route to this network is being sent to neighbors on other nets,
30331220Skarels  * mark this route as subnet so we don't have to propagate it too.
30431220Skarels  */
add_ptopt_localrt(ifp)30531220Skarels add_ptopt_localrt(ifp)
30631220Skarels 	register struct interface *ifp;
30731220Skarels {
30831220Skarels 	struct rt_entry *rt;
30931220Skarels 	struct sockaddr *dst;
31031220Skarels 	struct sockaddr_in net;
31131220Skarels 	int state;
31231220Skarels 
31331220Skarels 	state = RTS_INTERFACE | RTS_PASSIVE;
31431220Skarels 
31531220Skarels 	/* look for route to logical network */
316*69003Sbostic 	memset(&net, 0, sizeof (net));
31731220Skarels 	net.sin_family = AF_INET;
31831220Skarels 	net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
31931220Skarels 	dst = (struct sockaddr *)&net;
32031220Skarels 	rt = rtfind(dst);
32131220Skarels 	if (rt && rt->rt_state & RTS_INTERNAL)
32231220Skarels 		state |= RTS_SUBNET;
32331220Skarels 
32431220Skarels 	dst = &ifp->int_addr;
32531220Skarels 	if (rt = rtfind(dst)) {
32631220Skarels 		if (rt && rt->rt_state & RTS_INTERFACE)
32731220Skarels 			return;
32831220Skarels 		rtdelete(rt);
32931220Skarels 	}
33034661Skarels 	rtadd(dst, &loopaddr, 1, state);
3319019Ssam }
3329019Ssam 
3339019Ssam /*
3349019Ssam  * As a concession to the ARPANET we read a list of gateways
3359019Ssam  * from /etc/gateways and add them to our tables.  This file
3369019Ssam  * exists at each ARPANET gateway and indicates a set of ``remote''
3379019Ssam  * gateways (i.e. a gateway which we can't immediately determine
3389019Ssam  * if it's present or not as we can do for those directly connected
3399019Ssam  * at the hardware level).  If a gateway is marked ``passive''
3409019Ssam  * in the file, then we assume it doesn't have a routing process
3419019Ssam  * of our design and simply assume it's always present.  Those
3429019Ssam  * not marked passive are treated as if they were directly
3439019Ssam  * connected -- they're added into the interface list so we'll
3449019Ssam  * send them routing updates.
34531220Skarels  *
34631220Skarels  * PASSIVE ENTRIES AREN'T NEEDED OR USED ON GATEWAYS RUNNING EGP.
3479019Ssam  */
gwkludge()3489019Ssam gwkludge()
3499019Ssam {
3509019Ssam 	struct sockaddr_in dst, gate;
3519019Ssam 	FILE *fp;
3529019Ssam 	char *type, *dname, *gname, *qual, buf[BUFSIZ];
3539019Ssam 	struct interface *ifp;
35428906Skarels 	int metric, n;
35516327Skarels 	struct rt_entry route;
3569019Ssam 
35737292Sbostic 	fp = fopen(_PATH_GATEWAYS, "r");
3589019Ssam 	if (fp == NULL)
3599019Ssam 		return;
3609019Ssam 	qual = buf;
3619019Ssam 	dname = buf + 64;
3629019Ssam 	gname = buf + ((BUFSIZ - 64) / 3);
3639019Ssam 	type = buf + (((BUFSIZ - 64) * 2) / 3);
364*69003Sbostic 	memset(&dst, 0, sizeof (dst));
365*69003Sbostic 	memset(&gate, 0, sizeof (gate));
366*69003Sbostic 	memset(&route, 0, sizeof(route));
36730745Skarels /* format: {net | host} XX gateway XX metric DD [passive | external]\n */
3689019Ssam #define	readentry(fp) \
3699019Ssam 	fscanf((fp), "%s %s gateway %s metric %d %s\n", \
3709019Ssam 		type, dname, gname, &metric, qual)
3719019Ssam 	for (;;) {
37228906Skarels 		if ((n = readentry(fp)) == EOF)
3739019Ssam 			break;
37410245Ssam 		if (!getnetorhostname(type, dname, &dst))
3759019Ssam 			continue;
37610245Ssam 		if (!gethostnameornumber(gname, &gate))
3779019Ssam 			continue;
37834661Skarels 		if (metric == 0)			/* XXX */
37934661Skarels 			metric = 1;
38016327Skarels 		if (strcmp(qual, "passive") == 0) {
38116327Skarels 			/*
38216327Skarels 			 * Passive entries aren't placed in our tables,
38316327Skarels 			 * only the kernel's, so we don't copy all of the
38416327Skarels 			 * external routing information within a net.
38516327Skarels 			 * Internal machines should use the default
38616327Skarels 			 * route to a suitable gateway (like us).
38716327Skarels 			 */
38816327Skarels 			route.rt_dst = *(struct sockaddr *) &dst;
38916327Skarels 			route.rt_router = *(struct sockaddr *) &gate;
39016327Skarels 			route.rt_flags = RTF_UP;
39116327Skarels 			if (strcmp(type, "host") == 0)
39216327Skarels 				route.rt_flags |= RTF_HOST;
39316327Skarels 			if (metric)
39416327Skarels 				route.rt_flags |= RTF_GATEWAY;
39552583Ssklower 			(void) rtioctl(ADD, &route.rt_rt);
39616327Skarels 			continue;
39716327Skarels 		}
39827231Skarels 		if (strcmp(qual, "external") == 0) {
39927231Skarels 			/*
40027231Skarels 			 * Entries marked external are handled
40127231Skarels 			 * by other means, e.g. EGP,
40227231Skarels 			 * and are placed in our tables only
40327231Skarels 			 * to prevent overriding them
40427231Skarels 			 * with something else.
40527231Skarels 			 */
40627231Skarels 			rtadd(&dst, &gate, metric, RTS_EXTERNAL|RTS_PASSIVE);
40728906Skarels 			continue;
40827231Skarels 		}
40916327Skarels 		/* assume no duplicate entries */
41016327Skarels 		externalinterfaces++;
4119019Ssam 		ifp = (struct interface *)malloc(sizeof (*ifp));
412*69003Sbostic 		memset(ifp, 0, sizeof (*ifp));
4139019Ssam 		ifp->int_flags = IFF_REMOTE;
4149019Ssam 		/* can't identify broadcast capability */
4159019Ssam 		ifp->int_net = inet_netof(dst.sin_addr);
4169019Ssam 		if (strcmp(type, "host") == 0) {
4179019Ssam 			ifp->int_flags |= IFF_POINTOPOINT;
4189019Ssam 			ifp->int_dstaddr = *((struct sockaddr *)&dst);
4199019Ssam 		}
4209019Ssam 		ifp->int_addr = *((struct sockaddr *)&gate);
4219019Ssam 		ifp->int_metric = metric;
4229019Ssam 		ifp->int_next = ifnet;
4239019Ssam 		ifnet = ifp;
4249019Ssam 		addrouteforif(ifp);
4259019Ssam 	}
4269019Ssam 	fclose(fp);
4279019Ssam }
42810245Ssam 
getnetorhostname(type,name,sin)42910245Ssam getnetorhostname(type, name, sin)
43010245Ssam 	char *type, *name;
43110245Ssam 	struct sockaddr_in *sin;
43210245Ssam {
43310245Ssam 
43410245Ssam 	if (strcmp(type, "net") == 0) {
43510245Ssam 		struct netent *np = getnetbyname(name);
43610245Ssam 		int n;
43710245Ssam 
43810245Ssam 		if (np == 0)
43910245Ssam 			n = inet_network(name);
44011527Ssam 		else {
44111527Ssam 			if (np->n_addrtype != AF_INET)
44211527Ssam 				return (0);
44310245Ssam 			n = np->n_net;
44421842Skarels 			/*
44521842Skarels 			 * getnetbyname returns right-adjusted value.
44621842Skarels 			 */
44721842Skarels 			if (n < 128)
44821842Skarels 				n <<= IN_CLASSA_NSHIFT;
44921842Skarels 			else if (n < 65536)
45021842Skarels 				n <<= IN_CLASSB_NSHIFT;
45121842Skarels 			else
45221842Skarels 				n <<= IN_CLASSC_NSHIFT;
45311527Ssam 		}
45410245Ssam 		sin->sin_family = AF_INET;
45510245Ssam 		sin->sin_addr = inet_makeaddr(n, INADDR_ANY);
45610245Ssam 		return (1);
45710245Ssam 	}
45810245Ssam 	if (strcmp(type, "host") == 0) {
45910245Ssam 		struct hostent *hp = gethostbyname(name);
46010245Ssam 
46110245Ssam 		if (hp == 0)
46210245Ssam 			sin->sin_addr.s_addr = inet_addr(name);
46311527Ssam 		else {
46411527Ssam 			if (hp->h_addrtype != AF_INET)
46511527Ssam 				return (0);
466*69003Sbostic 			memmove(&sin->sin_addr, hp->h_addr, hp->h_length);
46711527Ssam 		}
46810245Ssam 		sin->sin_family = AF_INET;
46910245Ssam 		return (1);
47010245Ssam 	}
47110245Ssam 	return (0);
47210245Ssam }
47310245Ssam 
gethostnameornumber(name,sin)47410245Ssam gethostnameornumber(name, sin)
47510245Ssam 	char *name;
47610245Ssam 	struct sockaddr_in *sin;
47710245Ssam {
47810245Ssam 	struct hostent *hp;
47910245Ssam 
48010245Ssam 	hp = gethostbyname(name);
48110245Ssam 	if (hp) {
482*69003Sbostic 		memmove(&sin->sin_addr, hp->h_addr, hp->h_length);
48310245Ssam 		sin->sin_family = hp->h_addrtype;
48410245Ssam 		return (1);
48510245Ssam 	}
48610245Ssam 	sin->sin_addr.s_addr = inet_addr(name);
48710245Ssam 	sin->sin_family = AF_INET;
48810245Ssam 	return (sin->sin_addr.s_addr != -1);
48910245Ssam }
490