ANSI C; sprintf now returns an int.
[unix-history] / usr / src / sbin / XNSrouted / startup.c
CommitLineData
4a10c08d
KS
1/*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * Includes material written at Cornell University by Bill Nesheim,
7 * by permission of the author.
8 */
9
10
5e838d4d 11#ifndef lint
84f93e8f 12static char sccsid[] = "@(#)startup.c 5.5 (Berkeley) %G%";
4a10c08d 13#endif not lint
5e838d4d
KS
14
15/*
16 * Routing Table Management Daemon
17 */
18#include "defs.h"
19#include <sys/ioctl.h>
20#include <net/if.h>
21#include <nlist.h>
48681466 22#include <syslog.h>
5e838d4d
KS
23
24struct interface *ifnet;
5e838d4d
KS
25int lookforinterfaces = 1;
26int performnlist = 1;
84f93e8f 27int gateway = 0;
5e838d4d 28int externalinterfaces = 0; /* # of remote and local interfaces */
5e838d4d
KS
29char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
30
5e838d4d
KS
31
32/*
48681466
KS
33 * Find the network interfaces which have configured themselves.
34 * If the interface is present but not yet up (for example an
5e838d4d
KS
35 * ARPANET IMP), set the lookforinterfaces flag so we'll
36 * come back later and look again.
37 */
38ifinit()
39{
48681466
KS
40 struct interface ifs, *ifp;
41 int s, n;
48681466 42 struct ifconf ifc;
053f3ae9 43 char buf[(sizeof (struct ifreq ) * 20)];
48681466
KS
44 struct ifreq ifreq, *ifr;
45 u_long i;
5e838d4d 46
48681466
KS
47 if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
48 syslog(LOG_ERR, "socket: %m");
49 exit(1);
5e838d4d 50 }
48681466
KS
51 ifc.ifc_len = sizeof (buf);
52 ifc.ifc_buf = buf;
53 if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
54 syslog(LOG_ERR, "ioctl (get interface configuration)");
55 close(s);
56 return (0);
57 }
58 ifr = ifc.ifc_req;
5e838d4d 59 lookforinterfaces = 0;
48681466
KS
60 for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) {
61 bzero((char *)&ifs, sizeof(ifs));
62 ifs.int_addr = ifr->ifr_addr;
63 ifreq = *ifr;
64 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
65 syslog(LOG_ERR, "ioctl (get interface flags)");
66 continue;
67 }
68 ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
69 if ((ifs.int_flags & IFF_UP) == 0 ||
70 ifr->ifr_addr.sa_family == AF_UNSPEC) {
5e838d4d
KS
71 lookforinterfaces = 1;
72 continue;
73 }
48681466
KS
74 if (ifs.int_addr.sa_family != AF_NS)
75 continue;
76 if (ifs.int_flags & IFF_POINTOPOINT) {
77 if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
053f3ae9 78 syslog(LOG_ERR, "ioctl (get dstaddr): %m");
48681466
KS
79 continue;
80 }
81 ifs.int_dstaddr = ifreq.ifr_dstaddr;
82 }
83 if (ifs.int_flags & IFF_BROADCAST) {
84 if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
053f3ae9 85 syslog(LOG_ERR, "ioctl (get broadaddr: %m");
48681466
KS
86 continue;
87 }
88 ifs.int_broadaddr = ifreq.ifr_broadaddr;
5e838d4d 89 }
84f93e8f
KS
90 /*
91 * already known to us?
92 * what makes a POINTOPOINT if unique is its dst addr,
93 * NOT its source address
94 */
95 if ( ((ifs.int_flags & IFF_POINTOPOINT) &&
96 if_ifwithdstaddr(&ifs.int_dstaddr)) ||
97 ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) &&
98 if_ifwithaddr(&ifs.int_addr)))
99 continue;
48681466 100 /* no one cares about software loopback interfaces */
84f93e8f 101 if (strncmp(ifr->ifr_name,"lo", 2)==0)
48681466 102 continue;
5e838d4d
KS
103 ifp = (struct interface *)malloc(sizeof (struct interface));
104 if (ifp == 0) {
053f3ae9 105 syslog(LOG_ERR,"XNSrouted: out of memory\n");
5e838d4d
KS
106 break;
107 }
48681466 108 *ifp = ifs;
5e838d4d
KS
109 /*
110 * Count the # of directly connected networks
111 * and point to point links which aren't looped
112 * back to ourself. This is used below to
113 * decide if we should be a routing ``supplier''.
114 */
48681466
KS
115 if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
116 if_ifwithaddr(&ifs.int_dstaddr) == 0)
5e838d4d 117 externalinterfaces++;
84f93e8f
KS
118 /*
119 * If we have a point-to-point link, we want to act
120 * as a supplier even if it's our only interface,
121 * as that's the only way our peer on the other end
122 * can tell that the link is up.
123 */
124 if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
125 supplier = 1;
48681466 126 ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
5e838d4d 127 if (ifp->int_name == 0) {
053f3ae9 128 syslog(LOG_ERR,"XNSrouted: out of memory\n");
5e838d4d
KS
129 goto bad; /* ??? */
130 }
48681466 131 strcpy(ifp->int_name, ifr->ifr_name);
5e838d4d
KS
132 ifp->int_metric = 0;
133 ifp->int_next = ifnet;
5e838d4d
KS
134 ifnet = ifp;
135 traceinit(ifp);
136 addrouteforif(ifp);
137 }
138 if (externalinterfaces > 1 && supplier < 0)
139 supplier = 1;
48681466 140 close(s);
5e838d4d
KS
141 return;
142bad:
143 sleep(60);
48681466 144 close(s);
053f3ae9 145 sleep(60);
5e838d4d
KS
146 execv("/etc/XNSrouted", argv0);
147 _exit(0177);
148}
149
150addrouteforif(ifp)
151 struct interface *ifp;
152{
48681466 153 struct sockaddr_ns net;
5e838d4d
KS
154 struct sockaddr *dst;
155 int state, metric;
156 struct rt_entry *rt;
157
4a10c08d
KS
158 if (ifp->int_flags & IFF_POINTOPOINT) {
159 int (*match)();
160 register struct interface *ifp2 = ifnet;
161 register struct interface *ifprev = ifnet;
162
5e838d4d 163 dst = &ifp->int_dstaddr;
4a10c08d
KS
164
165 /* Search for interfaces with the same net */
166 ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq);
167 match = afswitch[dst->sa_family].af_netmatch;
168 if (match)
169 for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) {
170 if (ifp->int_flags & IFF_POINTOPOINT == 0)
171 continue;
172 if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) {
173 insque(&ifp2->int_sq,&ifp->int_sq);
174 break;
175 }
176 }
177 } else {
48681466 178 dst = &ifp->int_broadaddr;
5e838d4d
KS
179 }
180 rt = rtlookup(dst);
5e838d4d
KS
181 if (rt)
182 rtdelete(rt);
84f93e8f
KS
183 if (tracing)
184 fprintf(stderr, "Adding route to interface %s\n", ifp->int_name);
185 if (ifp->int_transitions++ > 0)
186 syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
48681466
KS
187 rtadd(dst, &ifp->int_addr, ifp->int_metric,
188 ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
5e838d4d 189}
84f93e8f 190