xref: /csrg-svn/sbin/XNSrouted/startup.c (revision 24322)
1*24322Ssklower /*
2*24322Ssklower  * Copyright (c) 1985 Regents of the University of California.
3*24322Ssklower  * All rights reserved.  The Berkeley software License Agreement
4*24322Ssklower  * specifies the terms and conditions for redistribution.
5*24322Ssklower  *
6*24322Ssklower  * Includes material written at Cornell University by Bill Nesheim,
7*24322Ssklower  * by permission of the author.
8*24322Ssklower  */
9*24322Ssklower 
10*24322Ssklower 
1124312Ssklower #ifndef lint
12*24322Ssklower static char sccsid[] = "@(#)startup.c	5.3 (Berkeley) 08/16/85";
13*24322Ssklower #endif not lint
1424312Ssklower 
1524312Ssklower /*
1624312Ssklower  * Routing Table Management Daemon
1724312Ssklower  */
1824312Ssklower #include "defs.h"
1924312Ssklower #include <sys/ioctl.h>
2024312Ssklower #include <net/if.h>
2124312Ssklower #include <nlist.h>
2224317Ssklower #include <syslog.h>
2324312Ssklower 
2424312Ssklower struct	interface *ifnet;
2524312Ssklower int	lookforinterfaces = 1;
2624312Ssklower int	performnlist = 1;
2724312Ssklower int	externalinterfaces = 0;		/* # of remote and local interfaces */
2824312Ssklower int	gateway = 0;		/* 1 if we are a gateway to parts beyond */
2924312Ssklower char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3024312Ssklower 
3124312Ssklower 
3224312Ssklower /*
3324317Ssklower  * Find the network interfaces which have configured themselves.
3424317Ssklower  * If the interface is present but not yet up (for example an
3524312Ssklower  * ARPANET IMP), set the lookforinterfaces flag so we'll
3624312Ssklower  * come back later and look again.
3724312Ssklower  */
3824312Ssklower ifinit()
3924312Ssklower {
4024317Ssklower 	struct interface ifs, *ifp;
4124317Ssklower 	int s, n;
4224317Ssklower 	char buf[BUFSIZ];
4324317Ssklower         struct ifconf ifc;
4424317Ssklower         struct ifreq ifreq, *ifr;
4524317Ssklower 	u_long i;
4624312Ssklower 
4724317Ssklower 	if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
4824317Ssklower 		syslog(LOG_ERR, "socket: %m");
4924317Ssklower 		exit(1);
5024312Ssklower 	}
5124317Ssklower         ifc.ifc_len = sizeof (buf);
5224317Ssklower         ifc.ifc_buf = buf;
5324317Ssklower         if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
5424317Ssklower                 syslog(LOG_ERR, "ioctl (get interface configuration)");
5524317Ssklower 		close(s);
5624317Ssklower                 return (0);
5724317Ssklower         }
5824317Ssklower         ifr = ifc.ifc_req;
5924312Ssklower 	lookforinterfaces = 0;
6024317Ssklower         for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) {
6124317Ssklower 		bzero((char *)&ifs, sizeof(ifs));
6224317Ssklower 		ifs.int_addr = ifr->ifr_addr;
6324317Ssklower 		ifreq = *ifr;
6424317Ssklower                 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
6524317Ssklower                         syslog(LOG_ERR, "ioctl (get interface flags)");
6624317Ssklower                         continue;
6724317Ssklower                 }
6824317Ssklower 		ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
6924317Ssklower 		if ((ifs.int_flags & IFF_UP) == 0 ||
7024317Ssklower 		    ifr->ifr_addr.sa_family == AF_UNSPEC) {
7124312Ssklower 			lookforinterfaces = 1;
7224312Ssklower 			continue;
7324312Ssklower 		}
7424317Ssklower 		/* already known to us? */
75*24322Ssklower 		/*if (if_ifwithaddr(&ifs.int_addr))
76*24322Ssklower 			continue;*/
7724317Ssklower 		/* argh, this'll have to change sometime */
7824317Ssklower 		if (ifs.int_addr.sa_family != AF_NS)
7924317Ssklower 			continue;
8024317Ssklower                 if (ifs.int_flags & IFF_POINTOPOINT) {
8124317Ssklower                         if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
8224317Ssklower                                 syslog(LOG_ERR, "ioctl (get dstaddr)");
8324317Ssklower                                 continue;
8424317Ssklower 			}
8524317Ssklower 			ifs.int_dstaddr = ifreq.ifr_dstaddr;
8624312Ssklower 		}
8724317Ssklower                 if (ifs.int_flags & IFF_BROADCAST) {
8824317Ssklower                         if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
8924317Ssklower                                 syslog(LOG_ERR, "ioctl (get broadaddr)");
9024317Ssklower                                 continue;
9124317Ssklower                         }
9224317Ssklower 			ifs.int_broadaddr = ifreq.ifr_broadaddr;
9324317Ssklower 		}
9424317Ssklower 		/* no one cares about software loopback interfaces */
9524317Ssklower 		if (strcmp(ifr->ifr_name,"lo0")==0)
9624317Ssklower 			continue;
9724312Ssklower 		ifp = (struct interface *)malloc(sizeof (struct interface));
9824312Ssklower 		if (ifp == 0) {
9924312Ssklower 			printf("routed: out of memory\n");
10024312Ssklower 			break;
10124312Ssklower 		}
10224317Ssklower 		*ifp = ifs;
10324312Ssklower 		/*
10424312Ssklower 		 * Count the # of directly connected networks
10524312Ssklower 		 * and point to point links which aren't looped
10624312Ssklower 		 * back to ourself.  This is used below to
10724312Ssklower 		 * decide if we should be a routing ``supplier''.
10824312Ssklower 		 */
10924317Ssklower 		if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
11024317Ssklower 		    if_ifwithaddr(&ifs.int_dstaddr) == 0)
11124312Ssklower 			externalinterfaces++;
11224317Ssklower 		ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
11324312Ssklower 		if (ifp->int_name == 0) {
11424312Ssklower 			fprintf(stderr, "routed: ifinit: out of memory\n");
11524312Ssklower 			goto bad;		/* ??? */
11624312Ssklower 		}
11724317Ssklower 		strcpy(ifp->int_name, ifr->ifr_name);
11824312Ssklower 		ifp->int_metric = 0;
11924312Ssklower 		ifp->int_next = ifnet;
12024312Ssklower 		ifnet = ifp;
12124312Ssklower 		traceinit(ifp);
12224312Ssklower 		addrouteforif(ifp);
12324312Ssklower 	}
12424312Ssklower 	if (externalinterfaces > 1 && supplier < 0)
12524312Ssklower 		supplier = 1;
12624317Ssklower 	close(s);
12724312Ssklower 	return;
12824312Ssklower bad:
12924312Ssklower 	sleep(60);
13024317Ssklower 	close(s);
13124312Ssklower 	execv("/etc/XNSrouted", argv0);
13224312Ssklower 	_exit(0177);
13324312Ssklower }
13424312Ssklower 
13524312Ssklower addrouteforif(ifp)
13624312Ssklower 	struct interface *ifp;
13724312Ssklower {
13824317Ssklower 	struct sockaddr_ns net;
13924312Ssklower 	struct sockaddr *dst;
14024312Ssklower 	int state, metric;
14124312Ssklower 	struct rt_entry *rt;
14224312Ssklower 
143*24322Ssklower 	if (ifp->int_flags & IFF_POINTOPOINT) {
144*24322Ssklower 		int (*match)();
145*24322Ssklower 		register struct interface *ifp2 = ifnet;
146*24322Ssklower 		register struct interface *ifprev = ifnet;
147*24322Ssklower 
14824312Ssklower 		dst = &ifp->int_dstaddr;
149*24322Ssklower 
150*24322Ssklower 		/* Search for interfaces with the same net */
151*24322Ssklower 		ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq);
152*24322Ssklower 		match = afswitch[dst->sa_family].af_netmatch;
153*24322Ssklower 		if (match)
154*24322Ssklower 		for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) {
155*24322Ssklower 			if (ifp->int_flags & IFF_POINTOPOINT == 0)
156*24322Ssklower 				continue;
157*24322Ssklower 			if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) {
158*24322Ssklower 				insque(&ifp2->int_sq,&ifp->int_sq);
159*24322Ssklower 				break;
160*24322Ssklower 			}
161*24322Ssklower 		}
162*24322Ssklower 	} else {
16324317Ssklower 		dst = &ifp->int_broadaddr;
16424312Ssklower 	}
16524312Ssklower 	rt = rtlookup(dst);
16624317Ssklower 	if (rt)
16724317Ssklower 		rtdelete(rt);
16824312Ssklower 	rtadd(dst, &ifp->int_addr, ifp->int_metric,
16924312Ssklower 		ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
17024312Ssklower }
171