2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1995 John Hay. All rights reserved.
7 * This file includes significant work done at Cornell University by
8 * Bill Nesheim. That work included by permission.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * $FreeBSD: src/usr.sbin/IPXrouted/startup.c,v 1.8.2.1 2000/07/01 10:46:25 ps Exp $
39 * $DragonFly: src/usr.sbin/IPXrouted/startup.c,v 1.4 2004/12/18 22:48:02 swildner Exp $
41 * @(#)startup.c 8.1 (Berkeley) 6/5/93
45 * Routing Table Management Daemon
49 #include <sys/param.h>
50 #include <sys/ioctl.h>
51 #include <sys/sysctl.h>
55 #include <net/if_dl.h>
61 struct interface
*ifnet
;
62 int lookforinterfaces
= 1;
65 int externalinterfaces
= 0; /* # of remote and local interfaces */
72 fprintf(stderr
, "IPXroute: ");
74 fprintf(stderr
, "%s: ", s
);
75 fprintf(stderr
, "%s\n", strerror(sverrno
));
80 struct rt_addrinfo info
;
81 /* Sleazy use of local variables throughout file, warning!!!! */
82 #define netmask info.rti_info[RTAX_NETMASK]
83 #define ifaaddr info.rti_info[RTAX_IFA]
84 #define brdaddr info.rti_info[RTAX_BRD]
87 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
88 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
91 rt_xaddrs(caddr_t cp
, caddr_t cplim
, struct rt_addrinfo
*rtinfo
)
96 bzero(rtinfo
->rti_info
, sizeof(rtinfo
->rti_info
));
97 for (i
= 0; (i
< RTAX_MAX
) && (cp
< cplim
); i
++) {
98 if ((rtinfo
->rti_addrs
& (1 << i
)) == 0)
100 rtinfo
->rti_info
[i
] = sa
= (struct sockaddr
*)cp
;
106 * Find the network interfaces which have configured themselves.
107 * If the interface is present but not yet up (for example an
108 * ARPANET IMP), set the lookforinterfaces flag so we'll
109 * come back later and look again.
114 struct interface ifs
, *ifp
;
116 int mib
[6], no_ipxaddr
= 0, flags
= 0;
117 char *buf
, *cplim
, *cp
;
118 struct if_msghdr
*ifm
;
119 struct ifa_msghdr
*ifam
;
120 struct sockaddr_dl
*sdl
= 0;
126 mib
[4] = NET_RT_IFLIST
;
128 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
129 quit("route-sysctl-estimate");
130 if ((buf
= malloc(needed
)) == NULL
)
132 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0)
133 lookforinterfaces
= 0;
134 cplim
= buf
+ needed
;
135 for (cp
= buf
; cp
< cplim
; cp
+= ifm
->ifm_msglen
) {
136 ifm
= (struct if_msghdr
*)cp
;
137 if (ifm
->ifm_type
== RTM_IFINFO
) {
138 bzero(&ifs
, sizeof(ifs
));
139 ifs
.int_flags
= flags
= ifm
->ifm_flags
| IFF_INTERFACE
;
140 if ((flags
& IFF_UP
) == 0 || no_ipxaddr
)
141 lookforinterfaces
= 1;
142 sdl
= (struct sockaddr_dl
*) (ifm
+ 1);
143 sdl
->sdl_data
[sdl
->sdl_nlen
] = 0;
147 if (ifm
->ifm_type
!= RTM_NEWADDR
)
148 quit("ifinit: out of sync");
149 if ((flags
& IFF_UP
) == 0)
151 ifam
= (struct ifa_msghdr
*)ifm
;
152 info
.rti_addrs
= ifam
->ifam_addrs
;
153 rt_xaddrs((char *)(ifam
+ 1), cp
+ ifam
->ifam_msglen
, &info
);
155 syslog(LOG_ERR
, "%s: (get addr)", sdl
->sdl_data
);
158 ifs
.int_addr
= *ifaaddr
;
159 if (ifs
.int_addr
.sa_family
!= AF_IPX
)
162 if (ifs
.int_flags
& IFF_POINTOPOINT
) {
164 syslog(LOG_ERR
, "%s: (get dstaddr)",
168 if (brdaddr
->sa_family
== AF_UNSPEC
) {
169 lookforinterfaces
= 1;
172 ifs
.int_dstaddr
= *brdaddr
;
174 if (ifs
.int_flags
& IFF_BROADCAST
) {
176 syslog(LOG_ERR
, "%s: (get broadaddr)",
180 ifs
.int_dstaddr
= *brdaddr
;
182 if (ifs
.int_flags
& IFF_LOOPBACK
) {
183 ifs
.int_dstaddr
= ifs
.int_addr
;
186 * already known to us?
187 * what makes a POINTOPOINT if unique is its dst addr,
188 * NOT its source address
190 if ( ((ifs
.int_flags
& IFF_POINTOPOINT
) &&
191 if_ifwithdstaddr(&ifs
.int_dstaddr
)) ||
192 ( ((ifs
.int_flags
& IFF_POINTOPOINT
) == 0) &&
193 if_ifwithaddr(&ifs
.int_addr
)))
195 ifp
= (struct interface
*)
196 malloc(sdl
->sdl_nlen
+ 1 + sizeof(ifs
));
198 syslog(LOG_ERR
, "IPXrouted: out of memory\n");
199 lookforinterfaces
= 1;
204 * Count the # of directly connected networks
205 * and point to point links which aren't looped
206 * back to ourself. This is used below to
207 * decide if we should be a routing ``supplier''.
209 if ((ifs
.int_flags
& IFF_POINTOPOINT
) == 0 ||
210 if_ifwithaddr(&ifs
.int_dstaddr
) == 0)
211 externalinterfaces
++;
213 * If we have a point-to-point link, we want to act
214 * as a supplier even if it's our only interface,
215 * as that's the only way our peer on the other end
216 * can tell that the link is up.
218 if ((ifs
.int_flags
& IFF_POINTOPOINT
) && supplier
< 0)
220 ifp
->int_name
= (char *)(ifp
+ 1);
221 strcpy(ifp
->int_name
, sdl
->sdl_data
);
223 ifp
->int_metric
= ifam
->ifam_metric
;
224 ifp
->int_next
= ifnet
;
229 if (externalinterfaces
> 1 && supplier
< 0)
235 addrouteforif(struct interface
*ifp
)
237 struct sockaddr_ipx net
;
238 struct sockaddr
*dst
;
241 if (ifp
->int_flags
& IFF_POINTOPOINT
) {
243 struct interface
*ifp2
= ifnet
;
245 dst
= &ifp
->int_dstaddr
;
247 /* Search for interfaces with the same net */
248 ifp
->int_sq
.n
= ifp
->int_sq
.p
= &(ifp
->int_sq
);
249 match
= afswitch
[dst
->sa_family
].af_netmatch
;
251 for (ifp2
= ifnet
; ifp2
; ifp2
=ifp2
->int_next
) {
252 if (ifp
->int_flags
& IFF_POINTOPOINT
== 0)
254 if ((*match
)(&ifp2
->int_dstaddr
,&ifp
->int_dstaddr
)) {
255 insque(&ifp2
->int_sq
,&ifp
->int_sq
);
260 bzero(&net
, sizeof(net
));
261 net
.sipx_family
= AF_IPX
;
262 net
.sipx_len
= sizeof (net
);
263 net
.sipx_addr
.x_net
= satoipx_addr(ifp
->int_broadaddr
).x_net
;
264 dst
= (struct sockaddr
*)&net
;
270 fprintf(stderr
, "Adding route to interface %s\n", ifp
->int_name
);
271 if (ifp
->int_transitions
++ > 0)
272 syslog(LOG_ERR
, "re-installing interface %s", ifp
->int_name
);
273 rtadd(dst
, &ifp
->int_addr
, ifp
->int_metric
, 0,
274 ifp
->int_flags
& (IFF_INTERFACE
|IFF_PASSIVE
|IFF_REMOTE
));