* Copyright (c) 1985 The Regents of the University of California.
* This file includes significant work done at Cornell University by
* Bill Nesheim. That work included by permission.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)startup.c 5.6 (Berkeley) %G%";
* Routing Table Management Daemon
int lookforinterfaces
= 1;
int externalinterfaces
= 0; /* # of remote and local interfaces */
char ether_broadcast_addr
[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
* Find the network interfaces which have configured themselves.
* If the interface is present but not yet up (for example an
* ARPANET IMP), set the lookforinterfaces flag so we'll
* come back later and look again.
struct interface ifs
, *ifp
;
char buf
[(sizeof (struct ifreq
) * 20)];
struct ifreq ifreq
, *ifr
;
if ((s
= socket(AF_NS
, SOCK_DGRAM
, 0)) < 0) {
syslog(LOG_ERR
, "socket: %m");
ifc
.ifc_len
= sizeof (buf
);
if (ioctl(s
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
syslog(LOG_ERR
, "ioctl (get interface configuration)");
for (n
= ifc
.ifc_len
/ sizeof (struct ifreq
); n
> 0; n
--, ifr
++) {
bzero((char *)&ifs
, sizeof(ifs
));
ifs
.int_addr
= ifr
->ifr_addr
;
if (ioctl(s
, SIOCGIFFLAGS
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "ioctl (get interface flags)");
ifs
.int_flags
= ifreq
.ifr_flags
| IFF_INTERFACE
;
if ((ifs
.int_flags
& IFF_UP
) == 0 ||
ifr
->ifr_addr
.sa_family
== AF_UNSPEC
) {
if (ifs
.int_addr
.sa_family
!= AF_NS
)
if (ifs
.int_flags
& IFF_POINTOPOINT
) {
if (ioctl(s
, SIOCGIFDSTADDR
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "ioctl (get dstaddr): %m");
ifs
.int_dstaddr
= ifreq
.ifr_dstaddr
;
if (ifs
.int_flags
& IFF_BROADCAST
) {
if (ioctl(s
, SIOCGIFBRDADDR
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "ioctl (get broadaddr: %m");
ifs
.int_broadaddr
= ifreq
.ifr_broadaddr
;
* what makes a POINTOPOINT if unique is its dst addr,
if ( ((ifs
.int_flags
& IFF_POINTOPOINT
) &&
if_ifwithdstaddr(&ifs
.int_dstaddr
)) ||
( ((ifs
.int_flags
& IFF_POINTOPOINT
) == 0) &&
if_ifwithaddr(&ifs
.int_addr
)))
/* no one cares about software loopback interfaces */
if (strncmp(ifr
->ifr_name
,"lo", 2)==0)
ifp
= (struct interface
*)malloc(sizeof (struct interface
));
syslog(LOG_ERR
,"XNSrouted: out of memory\n");
* Count the # of directly connected networks
* and point to point links which aren't looped
* back to ourself. This is used below to
* decide if we should be a routing ``supplier''.
if ((ifs
.int_flags
& IFF_POINTOPOINT
) == 0 ||
if_ifwithaddr(&ifs
.int_dstaddr
) == 0)
* If we have a point-to-point link, we want to act
* as a supplier even if it's our only interface,
* as that's the only way our peer on the other end
* can tell that the link is up.
if ((ifs
.int_flags
& IFF_POINTOPOINT
) && supplier
< 0)
ifp
->int_name
= malloc(strlen(ifr
->ifr_name
) + 1);
if (ifp
->int_name
== 0) {
syslog(LOG_ERR
,"XNSrouted: out of memory\n");
strcpy(ifp
->int_name
, ifr
->ifr_name
);
if (externalinterfaces
> 1 && supplier
< 0)
execv("/etc/XNSrouted", argv0
);
if (ifp
->int_flags
& IFF_POINTOPOINT
) {
register struct interface
*ifp2
= ifnet
;
register struct interface
*ifprev
= ifnet
;
/* Search for interfaces with the same net */
ifp
->int_sq
.n
= ifp
->int_sq
.p
= &(ifp
->int_sq
);
match
= afswitch
[dst
->sa_family
].af_netmatch
;
for (ifp2
= ifnet
; ifp2
; ifp2
=ifp2
->int_next
) {
if (ifp
->int_flags
& IFF_POINTOPOINT
== 0)
if ((*match
)(&ifp2
->int_dstaddr
,&ifp
->int_dstaddr
)) {
insque(&ifp2
->int_sq
,&ifp
->int_sq
);
dst
= &ifp
->int_broadaddr
;
fprintf(stderr
, "Adding route to interface %s\n", ifp
->int_name
);
if (ifp
->int_transitions
++ > 0)
syslog(LOG_ERR
, "re-installing interface %s", ifp
->int_name
);
rtadd(dst
, &ifp
->int_addr
, ifp
->int_metric
,
ifp
->int_flags
& (IFF_INTERFACE
|IFF_PASSIVE
|IFF_REMOTE
));