xref: /csrg-svn/sbin/XNSrouted/startup.c (revision 24317)
124312Ssklower #ifndef lint
224312Ssklower static char rcsid[] = "$Header$";
324312Ssklower #endif
424312Ssklower 
524312Ssklower /*
624312Ssklower  * Routing Table Management Daemon
724312Ssklower  */
824312Ssklower #include "defs.h"
924312Ssklower #include <sys/ioctl.h>
1024312Ssklower #include <net/if.h>
1124312Ssklower #include <nlist.h>
12*24317Ssklower #include <syslog.h>
1324312Ssklower 
1424312Ssklower struct	interface *ifnet;
1524312Ssklower int	lookforinterfaces = 1;
1624312Ssklower int	performnlist = 1;
1724312Ssklower int	externalinterfaces = 0;		/* # of remote and local interfaces */
1824312Ssklower int	gateway = 0;		/* 1 if we are a gateway to parts beyond */
1924312Ssklower char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2024312Ssklower 
2124312Ssklower 
2224312Ssklower /*
23*24317Ssklower  * Find the network interfaces which have configured themselves.
24*24317Ssklower  * If the interface is present but not yet up (for example an
2524312Ssklower  * ARPANET IMP), set the lookforinterfaces flag so we'll
2624312Ssklower  * come back later and look again.
2724312Ssklower  */
2824312Ssklower ifinit()
2924312Ssklower {
30*24317Ssklower 	struct interface ifs, *ifp;
31*24317Ssklower 	int s, n;
32*24317Ssklower 	char buf[BUFSIZ];
33*24317Ssklower         struct ifconf ifc;
34*24317Ssklower         struct ifreq ifreq, *ifr;
35*24317Ssklower 	u_long i;
3624312Ssklower 
37*24317Ssklower 	if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
38*24317Ssklower 		syslog(LOG_ERR, "socket: %m");
39*24317Ssklower 		exit(1);
4024312Ssklower 	}
41*24317Ssklower         ifc.ifc_len = sizeof (buf);
42*24317Ssklower         ifc.ifc_buf = buf;
43*24317Ssklower         if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
44*24317Ssklower                 syslog(LOG_ERR, "ioctl (get interface configuration)");
45*24317Ssklower 		close(s);
46*24317Ssklower                 return (0);
47*24317Ssklower         }
48*24317Ssklower         ifr = ifc.ifc_req;
4924312Ssklower 	lookforinterfaces = 0;
50*24317Ssklower         for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) {
51*24317Ssklower 		bzero((char *)&ifs, sizeof(ifs));
52*24317Ssklower 		ifs.int_addr = ifr->ifr_addr;
53*24317Ssklower 		ifreq = *ifr;
54*24317Ssklower                 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
55*24317Ssklower                         syslog(LOG_ERR, "ioctl (get interface flags)");
56*24317Ssklower                         continue;
57*24317Ssklower                 }
58*24317Ssklower 		ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
59*24317Ssklower 		if ((ifs.int_flags & IFF_UP) == 0 ||
60*24317Ssklower 		    ifr->ifr_addr.sa_family == AF_UNSPEC) {
6124312Ssklower 			lookforinterfaces = 1;
6224312Ssklower 			continue;
6324312Ssklower 		}
64*24317Ssklower 		/* already known to us? */
65*24317Ssklower 		if (if_ifwithaddr(&ifs.int_addr))
66*24317Ssklower 			continue;
67*24317Ssklower 		/* argh, this'll have to change sometime */
68*24317Ssklower 		if (ifs.int_addr.sa_family != AF_NS)
69*24317Ssklower 			continue;
70*24317Ssklower                 if (ifs.int_flags & IFF_POINTOPOINT) {
71*24317Ssklower                         if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
72*24317Ssklower                                 syslog(LOG_ERR, "ioctl (get dstaddr)");
73*24317Ssklower                                 continue;
74*24317Ssklower 			}
75*24317Ssklower 			ifs.int_dstaddr = ifreq.ifr_dstaddr;
7624312Ssklower 		}
77*24317Ssklower                 if (ifs.int_flags & IFF_BROADCAST) {
78*24317Ssklower                         if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
79*24317Ssklower                                 syslog(LOG_ERR, "ioctl (get broadaddr)");
80*24317Ssklower                                 continue;
81*24317Ssklower                         }
82*24317Ssklower 			ifs.int_broadaddr = ifreq.ifr_broadaddr;
83*24317Ssklower 		}
84*24317Ssklower 		/* no one cares about software loopback interfaces */
85*24317Ssklower 		if (strcmp(ifr->ifr_name,"lo0")==0)
86*24317Ssklower 			continue;
8724312Ssklower 		ifp = (struct interface *)malloc(sizeof (struct interface));
8824312Ssklower 		if (ifp == 0) {
8924312Ssklower 			printf("routed: out of memory\n");
9024312Ssklower 			break;
9124312Ssklower 		}
92*24317Ssklower 		*ifp = ifs;
9324312Ssklower 		/*
9424312Ssklower 		 * Count the # of directly connected networks
9524312Ssklower 		 * and point to point links which aren't looped
9624312Ssklower 		 * back to ourself.  This is used below to
9724312Ssklower 		 * decide if we should be a routing ``supplier''.
9824312Ssklower 		 */
99*24317Ssklower 		if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
100*24317Ssklower 		    if_ifwithaddr(&ifs.int_dstaddr) == 0)
10124312Ssklower 			externalinterfaces++;
102*24317Ssklower 		ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
10324312Ssklower 		if (ifp->int_name == 0) {
10424312Ssklower 			fprintf(stderr, "routed: ifinit: out of memory\n");
10524312Ssklower 			goto bad;		/* ??? */
10624312Ssklower 		}
107*24317Ssklower 		strcpy(ifp->int_name, ifr->ifr_name);
10824312Ssklower 		ifp->int_metric = 0;
10924312Ssklower 		ifp->int_next = ifnet;
11024312Ssklower 		ifnet = ifp;
11124312Ssklower 		traceinit(ifp);
11224312Ssklower 		addrouteforif(ifp);
11324312Ssklower 	}
11424312Ssklower 	if (externalinterfaces > 1 && supplier < 0)
11524312Ssklower 		supplier = 1;
116*24317Ssklower 	close(s);
11724312Ssklower 	return;
11824312Ssklower bad:
11924312Ssklower 	sleep(60);
120*24317Ssklower 	close(s);
12124312Ssklower 	execv("/etc/XNSrouted", argv0);
12224312Ssklower 	_exit(0177);
12324312Ssklower }
12424312Ssklower 
12524312Ssklower addrouteforif(ifp)
12624312Ssklower 	struct interface *ifp;
12724312Ssklower {
128*24317Ssklower 	struct sockaddr_ns net;
12924312Ssklower 	struct sockaddr *dst;
13024312Ssklower 	int state, metric;
13124312Ssklower 	struct rt_entry *rt;
13224312Ssklower 
13324312Ssklower 	if (ifp->int_flags & IFF_POINTOPOINT)
13424312Ssklower 		dst = &ifp->int_dstaddr;
13524312Ssklower 	else {
136*24317Ssklower 		dst = &ifp->int_broadaddr;
13724312Ssklower 	}
13824312Ssklower 	rt = rtlookup(dst);
139*24317Ssklower 	if (rt)
140*24317Ssklower 		rtdelete(rt);
14124312Ssklower 	rtadd(dst, &ifp->int_addr, ifp->int_metric,
14224312Ssklower 		ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
14324312Ssklower }
14424312Ssklower 
145