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>
62 struct interface
*ifnet
;
63 int lookforinterfaces
= 1;
66 int externalinterfaces
= 0; /* # of remote and local interfaces */
73 fprintf(stderr
, "IPXroute: ");
75 fprintf(stderr
, "%s: ", s
);
76 fprintf(stderr
, "%s\n", strerror(sverrno
));
81 struct rt_addrinfo info
;
82 /* Sleazy use of local variables throughout file, warning!!!! */
83 #define netmask info.rti_info[RTAX_NETMASK]
84 #define ifaaddr info.rti_info[RTAX_IFA]
85 #define brdaddr info.rti_info[RTAX_BRD]
88 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
89 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
92 rt_xaddrs(caddr_t cp
, caddr_t cplim
, struct rt_addrinfo
*rtinfo
)
97 bzero(rtinfo
->rti_info
, sizeof(rtinfo
->rti_info
));
98 for (i
= 0; (i
< RTAX_MAX
) && (cp
< cplim
); i
++) {
99 if ((rtinfo
->rti_addrs
& (1 << i
)) == 0)
101 rtinfo
->rti_info
[i
] = sa
= (struct sockaddr
*)cp
;
107 * Find the network interfaces which have configured themselves.
108 * If the interface is present but not yet up (for example an
109 * ARPANET IMP), set the lookforinterfaces flag so we'll
110 * come back later and look again.
115 struct interface ifs
, *ifp
;
117 int mib
[6], no_ipxaddr
= 0, flags
= 0;
118 char *buf
, *cplim
, *cp
;
119 struct if_msghdr
*ifm
;
120 struct ifa_msghdr
*ifam
;
121 struct sockaddr_dl
*sdl
= 0;
127 mib
[4] = NET_RT_IFLIST
;
129 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
130 quit("route-sysctl-estimate");
131 if ((buf
= malloc(needed
)) == NULL
)
133 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0)
134 lookforinterfaces
= 0;
135 cplim
= buf
+ needed
;
136 for (cp
= buf
; cp
< cplim
; cp
+= ifm
->ifm_msglen
) {
137 ifm
= (struct if_msghdr
*)cp
;
138 if (ifm
->ifm_type
== RTM_IFINFO
) {
139 bzero(&ifs
, sizeof(ifs
));
140 ifs
.int_flags
= flags
= ifm
->ifm_flags
| IFF_INTERFACE
;
141 if ((flags
& IFF_UP
) == 0 || no_ipxaddr
)
142 lookforinterfaces
= 1;
143 sdl
= (struct sockaddr_dl
*) (ifm
+ 1);
144 sdl
->sdl_data
[sdl
->sdl_nlen
] = 0;
148 if (ifm
->ifm_type
!= RTM_NEWADDR
)
149 quit("ifinit: out of sync");
150 if ((flags
& IFF_UP
) == 0)
152 ifam
= (struct ifa_msghdr
*)ifm
;
153 info
.rti_addrs
= ifam
->ifam_addrs
;
154 rt_xaddrs((char *)(ifam
+ 1), cp
+ ifam
->ifam_msglen
, &info
);
156 syslog(LOG_ERR
, "%s: (get addr)", sdl
->sdl_data
);
159 ifs
.int_addr
= *ifaaddr
;
160 if (ifs
.int_addr
.sa_family
!= AF_IPX
)
163 if (ifs
.int_flags
& IFF_POINTOPOINT
) {
165 syslog(LOG_ERR
, "%s: (get dstaddr)",
169 if (brdaddr
->sa_family
== AF_UNSPEC
) {
170 lookforinterfaces
= 1;
173 ifs
.int_dstaddr
= *brdaddr
;
175 if (ifs
.int_flags
& IFF_BROADCAST
) {
177 syslog(LOG_ERR
, "%s: (get broadaddr)",
181 ifs
.int_dstaddr
= *brdaddr
;
183 if (ifs
.int_flags
& IFF_LOOPBACK
) {
184 ifs
.int_dstaddr
= ifs
.int_addr
;
187 * already known to us?
188 * what makes a POINTOPOINT if unique is its dst addr,
189 * NOT its source address
191 if ( ((ifs
.int_flags
& IFF_POINTOPOINT
) &&
192 if_ifwithdstaddr(&ifs
.int_dstaddr
)) ||
193 ( ((ifs
.int_flags
& IFF_POINTOPOINT
) == 0) &&
194 if_ifwithaddr(&ifs
.int_addr
)))
196 ifp
= (struct interface
*)
197 malloc(sdl
->sdl_nlen
+ 1 + sizeof(ifs
));
199 syslog(LOG_ERR
, "IPXrouted: out of memory\n");
200 lookforinterfaces
= 1;
205 * Count the # of directly connected networks
206 * and point to point links which aren't looped
207 * back to ourself. This is used below to
208 * decide if we should be a routing ``supplier''.
210 if ((ifs
.int_flags
& IFF_POINTOPOINT
) == 0 ||
211 if_ifwithaddr(&ifs
.int_dstaddr
) == 0)
212 externalinterfaces
++;
214 * If we have a point-to-point link, we want to act
215 * as a supplier even if it's our only interface,
216 * as that's the only way our peer on the other end
217 * can tell that the link is up.
219 if ((ifs
.int_flags
& IFF_POINTOPOINT
) && supplier
< 0)
221 ifp
->int_name
= (char *)(ifp
+ 1);
222 strcpy(ifp
->int_name
, sdl
->sdl_data
);
224 ifp
->int_metric
= ifam
->ifam_metric
;
225 ifp
->int_next
= ifnet
;
230 if (externalinterfaces
> 1 && supplier
< 0)
236 addrouteforif(struct interface
*ifp
)
238 struct sockaddr_ipx net
;
239 struct sockaddr
*dst
;
242 if (ifp
->int_flags
& IFF_POINTOPOINT
) {
244 struct interface
*ifp2
= ifnet
;
246 dst
= &ifp
->int_dstaddr
;
248 /* Search for interfaces with the same net */
249 ifp
->int_sq
.n
= ifp
->int_sq
.p
= &(ifp
->int_sq
);
250 match
= afswitch
[dst
->sa_family
].af_netmatch
;
252 for (ifp2
= ifnet
; ifp2
; ifp2
=ifp2
->int_next
) {
253 if ((ifp
->int_flags
& IFF_POINTOPOINT
) == 0)
255 if ((*match
)(&ifp2
->int_dstaddr
,&ifp
->int_dstaddr
)) {
256 insque(&ifp2
->int_sq
,&ifp
->int_sq
);
261 bzero(&net
, sizeof(net
));
262 net
.sipx_family
= AF_IPX
;
263 net
.sipx_len
= sizeof (net
);
264 net
.sipx_addr
.x_net
= satoipx_addr(ifp
->int_broadaddr
).x_net
;
265 dst
= (struct sockaddr
*)&net
;
271 fprintf(stderr
, "Adding route to interface %s\n", ifp
->int_name
);
272 if (ifp
->int_transitions
++ > 0)
273 syslog(LOG_ERR
, "re-installing interface %s", ifp
->int_name
);
274 rtadd(dst
, &ifp
->int_addr
, ifp
->int_metric
, 0,
275 ifp
->int_flags
& (IFF_INTERFACE
|IFF_PASSIVE
|IFF_REMOTE
));