Removed all patch kit headers, sccsid and rcsid strings, put $Id$ in, some
[unix-history] / usr.sbin / XNSrouted / startup.c
CommitLineData
18916298
RG
1/*
2 * Copyright (c) 1985 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This file includes significant work done at Cornell University by
6 * Bill Nesheim. That work included by permission.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38static char sccsid[] = "@(#)startup.c 5.11 (Berkeley) 2/26/91";
39#endif /* not lint */
40
41/*
42 * Routing Table Management Daemon
43 */
44#include "defs.h"
45#include <sys/ioctl.h>
46#include <net/if.h>
47#include <nlist.h>
48#include <stdlib.h>
49
50struct interface *ifnet;
51int lookforinterfaces = 1;
52int performnlist = 1;
53int gateway = 0;
54int externalinterfaces = 0; /* # of remote and local interfaces */
55char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
56
57
58/*
59 * Find the network interfaces which have configured themselves.
60 * If the interface is present but not yet up (for example an
61 * ARPANET IMP), set the lookforinterfaces flag so we'll
62 * come back later and look again.
63 */
64ifinit()
65{
66 struct interface ifs, *ifp;
67 int s;
68 struct ifconf ifc;
69 char buf[BUFSIZ], *cp, *cplim;
70 struct ifreq ifreq, *ifr;
71 u_long i;
72
73 if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
74 syslog(LOG_ERR, "socket: %m");
75 exit(1);
76 }
77 ifc.ifc_len = sizeof (buf);
78 ifc.ifc_buf = buf;
79 if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
80 syslog(LOG_ERR, "ioctl (get interface configuration)");
81 close(s);
82 exit(1);
83 }
84 ifr = ifc.ifc_req;
85 lookforinterfaces = 0;
86#ifdef RTM_ADD
87#define max(a, b) (a > b ? a : b)
88#define size(p) max((p).sa_len, sizeof(p))
89#else
90#define size(p) (sizeof (p))
91#endif
92 cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
93 for (cp = buf; cp < cplim;
94 cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
95 ifr = (struct ifreq *)cp;
96 bzero((char *)&ifs, sizeof(ifs));
97 ifs.int_addr = ifr->ifr_addr;
98 ifreq = *ifr;
99 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
100 syslog(LOG_ERR, "ioctl (get interface flags)");
101 continue;
102 }
103 ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
104 if ((ifs.int_flags & IFF_UP) == 0 ||
105 ifr->ifr_addr.sa_family == AF_UNSPEC) {
106 lookforinterfaces = 1;
107 continue;
108 }
109 if (ifs.int_addr.sa_family != AF_NS)
110 continue;
111 if (ifs.int_flags & IFF_POINTOPOINT) {
112 if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
113 syslog(LOG_ERR, "ioctl (get dstaddr): %m");
114 continue;
115 }
116 ifs.int_dstaddr = ifreq.ifr_dstaddr;
117 }
118 if (ifs.int_flags & IFF_BROADCAST) {
119 if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
120 syslog(LOG_ERR, "ioctl (get broadaddr: %m");
121 continue;
122 }
123 ifs.int_broadaddr = ifreq.ifr_broadaddr;
124 }
125 /*
126 * already known to us?
127 * what makes a POINTOPOINT if unique is its dst addr,
128 * NOT its source address
129 */
130 if ( ((ifs.int_flags & IFF_POINTOPOINT) &&
131 if_ifwithdstaddr(&ifs.int_dstaddr)) ||
132 ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) &&
133 if_ifwithaddr(&ifs.int_addr)))
134 continue;
135 /* no one cares about software loopback interfaces */
136 if (strncmp(ifr->ifr_name,"lo", 2)==0)
137 continue;
138 ifp = (struct interface *)malloc(sizeof (struct interface));
139 if (ifp == 0) {
140 syslog(LOG_ERR,"XNSrouted: out of memory\n");
141 break;
142 }
143 *ifp = ifs;
144 /*
145 * Count the # of directly connected networks
146 * and point to point links which aren't looped
147 * back to ourself. This is used below to
148 * decide if we should be a routing ``supplier''.
149 */
150 if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
151 if_ifwithaddr(&ifs.int_dstaddr) == 0)
152 externalinterfaces++;
153 /*
154 * If we have a point-to-point link, we want to act
155 * as a supplier even if it's our only interface,
156 * as that's the only way our peer on the other end
157 * can tell that the link is up.
158 */
159 if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
160 supplier = 1;
161 ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
162 if (ifp->int_name == 0) {
163 syslog(LOG_ERR,"XNSrouted: out of memory\n");
164 exit(1);
165 }
166 strcpy(ifp->int_name, ifr->ifr_name);
167 ifp->int_metric = 0;
168 ifp->int_next = ifnet;
169 ifnet = ifp;
170 traceinit(ifp);
171 addrouteforif(ifp);
172 }
173 if (externalinterfaces > 1 && supplier < 0)
174 supplier = 1;
175 close(s);
176}
177
178addrouteforif(ifp)
179 struct interface *ifp;
180{
181 struct sockaddr_ns net;
182 struct sockaddr *dst;
183 int state, metric;
184 struct rt_entry *rt;
185
186 if (ifp->int_flags & IFF_POINTOPOINT) {
187 int (*match)();
188 register struct interface *ifp2 = ifnet;
189 register struct interface *ifprev = ifnet;
190
191 dst = &ifp->int_dstaddr;
192
193 /* Search for interfaces with the same net */
194 ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq);
195 match = afswitch[dst->sa_family].af_netmatch;
196 if (match)
197 for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) {
198 if (ifp->int_flags & IFF_POINTOPOINT == 0)
199 continue;
200 if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) {
201 insque(&ifp2->int_sq,&ifp->int_sq);
202 break;
203 }
204 }
205 } else {
206 dst = &ifp->int_broadaddr;
207 }
208 rt = rtlookup(dst);
209 if (rt)
210 rtdelete(rt);
211 if (tracing)
212 fprintf(stderr, "Adding route to interface %s\n", ifp->int_name);
213 if (ifp->int_transitions++ > 0)
214 syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
215 rtadd(dst, &ifp->int_addr, ifp->int_metric,
216 ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
217}
218