|
|
1.1 root 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:
11: #ifndef lint
12: static char sccsid[] = "@(#)startup.c 5.5 (Berkeley) 2/14/86";
13: #endif not lint
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>
22: #include <syslog.h>
23:
24: struct interface *ifnet;
25: int lookforinterfaces = 1;
26: int performnlist = 1;
27: int gateway = 0;
28: int externalinterfaces = 0; /* # of remote and local interfaces */
29: char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
30:
31:
32: /*
33: * Find the network interfaces which have configured themselves.
34: * If the interface is present but not yet up (for example an
35: * ARPANET IMP), set the lookforinterfaces flag so we'll
36: * come back later and look again.
37: */
38: ifinit()
39: {
40: struct interface ifs, *ifp;
41: int s, n;
42: struct ifconf ifc;
43: char buf[(sizeof (struct ifreq ) * 20)];
44: struct ifreq ifreq, *ifr;
45: u_long i;
46:
47: if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
48: syslog(LOG_ERR, "socket: %m");
49: exit(1);
50: }
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;
59: lookforinterfaces = 0;
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) {
71: lookforinterfaces = 1;
72: continue;
73: }
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) {
78: syslog(LOG_ERR, "ioctl (get dstaddr): %m");
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) {
85: syslog(LOG_ERR, "ioctl (get broadaddr: %m");
86: continue;
87: }
88: ifs.int_broadaddr = ifreq.ifr_broadaddr;
89: }
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;
100: /* no one cares about software loopback interfaces */
101: if (strncmp(ifr->ifr_name,"lo", 2)==0)
102: continue;
103: ifp = (struct interface *)malloc(sizeof (struct interface));
104: if (ifp == 0) {
105: syslog(LOG_ERR,"XNSrouted: out of memory\n");
106: break;
107: }
108: *ifp = ifs;
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: */
115: if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
116: if_ifwithaddr(&ifs.int_dstaddr) == 0)
117: externalinterfaces++;
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;
126: ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
127: if (ifp->int_name == 0) {
128: syslog(LOG_ERR,"XNSrouted: out of memory\n");
129: goto bad; /* ??? */
130: }
131: strcpy(ifp->int_name, ifr->ifr_name);
132: ifp->int_metric = 0;
133: ifp->int_next = ifnet;
134: ifnet = ifp;
135: traceinit(ifp);
136: addrouteforif(ifp);
137: }
138: if (externalinterfaces > 1 && supplier < 0)
139: supplier = 1;
140: close(s);
141: return;
142: bad:
143: sleep(60);
144: close(s);
145: sleep(60);
146: execv("/etc/XNSrouted", argv0);
147: _exit(0177);
148: }
149:
150: addrouteforif(ifp)
151: struct interface *ifp;
152: {
153: struct sockaddr_ns net;
154: struct sockaddr *dst;
155: int state, metric;
156: struct rt_entry *rt;
157:
158: if (ifp->int_flags & IFF_POINTOPOINT) {
159: int (*match)();
160: register struct interface *ifp2 = ifnet;
161: register struct interface *ifprev = ifnet;
162:
163: dst = &ifp->int_dstaddr;
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 {
178: dst = &ifp->int_broadaddr;
179: }
180: rt = rtlookup(dst);
181: if (rt)
182: rtdelete(rt);
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);
187: rtadd(dst, &ifp->int_addr, ifp->int_metric,
188: ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
189: }
190:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.