|
|
1.1 root 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 are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)startup.c 5.9 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*
28: * Routing Table Management Daemon
29: */
30: #include "defs.h"
31: #include <sys/ioctl.h>
32: #include <net/if.h>
33: #include <nlist.h>
34: #include <syslog.h>
35:
36: struct interface *ifnet;
37: int lookforinterfaces = 1;
38: int performnlist = 1;
39: int gateway = 0;
40: int externalinterfaces = 0; /* # of remote and local interfaces */
41: char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
42:
43:
44: /*
45: * Find the network interfaces which have configured themselves.
46: * If the interface is present but not yet up (for example an
47: * ARPANET IMP), set the lookforinterfaces flag so we'll
48: * come back later and look again.
49: */
50: ifinit()
51: {
52: struct interface ifs, *ifp;
53: int s;
54: struct ifconf ifc;
55: char buf[BUFSIZ], *cp, *cplim;
56: struct ifreq ifreq, *ifr;
57: u_long i;
58:
59: if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
60: syslog(LOG_ERR, "socket: %m");
61: exit(1);
62: }
63: ifc.ifc_len = sizeof (buf);
64: ifc.ifc_buf = buf;
65: if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
66: syslog(LOG_ERR, "ioctl (get interface configuration)");
67: close(s);
68: exit(1);
69: }
70: ifr = ifc.ifc_req;
71: lookforinterfaces = 0;
72: #ifdef RTM_ADD
73: #define max(a, b) (a > b ? a : b)
74: #define size(p) max((p).sa_len, sizeof(p))
75: #else
76: #define size(p) (sizeof (p))
77: #endif
78: cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
79: for (cp = buf; cp < cplim;
80: cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
81: bzero((char *)&ifs, sizeof(ifs));
82: ifs.int_addr = ifr->ifr_addr;
83: ifreq = *ifr;
84: if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
85: syslog(LOG_ERR, "ioctl (get interface flags)");
86: continue;
87: }
88: ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
89: if ((ifs.int_flags & IFF_UP) == 0 ||
90: ifr->ifr_addr.sa_family == AF_UNSPEC) {
91: lookforinterfaces = 1;
92: continue;
93: }
94: if (ifs.int_addr.sa_family != AF_NS)
95: continue;
96: if (ifs.int_flags & IFF_POINTOPOINT) {
97: if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
98: syslog(LOG_ERR, "ioctl (get dstaddr): %m");
99: continue;
100: }
101: ifs.int_dstaddr = ifreq.ifr_dstaddr;
102: }
103: if (ifs.int_flags & IFF_BROADCAST) {
104: if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
105: syslog(LOG_ERR, "ioctl (get broadaddr: %m");
106: continue;
107: }
108: ifs.int_broadaddr = ifreq.ifr_broadaddr;
109: }
110: /*
111: * already known to us?
112: * what makes a POINTOPOINT if unique is its dst addr,
113: * NOT its source address
114: */
115: if ( ((ifs.int_flags & IFF_POINTOPOINT) &&
116: if_ifwithdstaddr(&ifs.int_dstaddr)) ||
117: ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) &&
118: if_ifwithaddr(&ifs.int_addr)))
119: continue;
120: /* no one cares about software loopback interfaces */
121: if (strncmp(ifr->ifr_name,"lo", 2)==0)
122: continue;
123: ifp = (struct interface *)malloc(sizeof (struct interface));
124: if (ifp == 0) {
125: syslog(LOG_ERR,"XNSrouted: out of memory\n");
126: break;
127: }
128: *ifp = ifs;
129: /*
130: * Count the # of directly connected networks
131: * and point to point links which aren't looped
132: * back to ourself. This is used below to
133: * decide if we should be a routing ``supplier''.
134: */
135: if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
136: if_ifwithaddr(&ifs.int_dstaddr) == 0)
137: externalinterfaces++;
138: /*
139: * If we have a point-to-point link, we want to act
140: * as a supplier even if it's our only interface,
141: * as that's the only way our peer on the other end
142: * can tell that the link is up.
143: */
144: if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
145: supplier = 1;
146: ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
147: if (ifp->int_name == 0) {
148: syslog(LOG_ERR,"XNSrouted: out of memory\n");
149: exit(1);
150: }
151: strcpy(ifp->int_name, ifr->ifr_name);
152: ifp->int_metric = 0;
153: ifp->int_next = ifnet;
154: ifnet = ifp;
155: traceinit(ifp);
156: addrouteforif(ifp);
157: }
158: if (externalinterfaces > 1 && supplier < 0)
159: supplier = 1;
160: close(s);
161: }
162:
163: addrouteforif(ifp)
164: struct interface *ifp;
165: {
166: struct sockaddr_ns net;
167: struct sockaddr *dst;
168: int state, metric;
169: struct rt_entry *rt;
170:
171: if (ifp->int_flags & IFF_POINTOPOINT) {
172: int (*match)();
173: register struct interface *ifp2 = ifnet;
174: register struct interface *ifprev = ifnet;
175:
176: dst = &ifp->int_dstaddr;
177:
178: /* Search for interfaces with the same net */
179: ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq);
180: match = afswitch[dst->sa_family].af_netmatch;
181: if (match)
182: for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) {
183: if (ifp->int_flags & IFF_POINTOPOINT == 0)
184: continue;
185: if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) {
186: insque(&ifp2->int_sq,&ifp->int_sq);
187: break;
188: }
189: }
190: } else {
191: dst = &ifp->int_broadaddr;
192: }
193: rt = rtlookup(dst);
194: if (rt)
195: rtdelete(rt);
196: if (tracing)
197: fprintf(stderr, "Adding route to interface %s\n", ifp->int_name);
198: if (ifp->int_transitions++ > 0)
199: syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
200: rtadd(dst, &ifp->int_addr, ifp->int_metric,
201: ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
202: }
203:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.