static char rcsid
[] = "$Header$";
* Routing Table Management Daemon
int lookforinterfaces
= 1;
int externalinterfaces
= 0; /* # of remote and local interfaces */
int gateway
= 0; /* 1 if we are a gateway to parts beyond */
char ether_broadcast_addr
[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
* Probe the kernel through /dev/kmem to 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.
char name
[32], *cp
, *index();
struct sockaddr ifaddr
, ifdstaddr
;
if (nl
[N_IFNET
].n_value
== 0) {
printf("ifnet: not in namelist\n");
kmem
= open("/dev/kmem", 0);
if (lseek(kmem
, (long)nl
[N_IFNET
].n_value
, 0) == -1 ||
read(kmem
, (char *)&next
, sizeof (next
)) != sizeof (next
)) {
printf("ifnet: error reading kmem\n");
if (lseek(kmem
, (long)next
, 0) == -1 ||
read(kmem
, (char *)&ifs
, sizeof (ifs
)) != sizeof (ifs
)) {
if ((ifs
.if_flags
& IFF_UP
) == 0) {
/* Only interested in af XNS */
for( j
= 0; j
< NIFADDR
; j
++) {
if (ifs
.if_addr
[j
].sa_family
!= AF_XNS
)
/* already known to us? */
if (if_ifwithaddr(&ifs
.if_addr
[j
]))
ifdstaddr
= ifs
.if_dstaddr
[j
];
ifp
= (struct interface
*)malloc(sizeof (struct interface
));
printf("routed: 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
.if_flags
& IFF_POINTOPOINT
) == 0 ||
if_ifwithaddr(ifdstaddr
) == 0)
if ((ifs
.if_flags
& IFF_LOCAL
) == 0 && gateway
== 0) {
* If we have an interface to a non-local network,
* we are a candidate for use as a gateway.
lseek(kmem
, ifs
.if_name
, 0);
read(kmem
, name
, sizeof (name
));
name
[sizeof (name
) - 1] = '\0';
*cp
++ = ifs
.if_unit
+ '0';
ifp
->int_name
= malloc(strlen(name
) + 1);
if (ifp
->int_name
== 0) {
fprintf(stderr
, "routed: ifinit: out of memory\n");
strcpy(ifp
->int_name
, name
);
ifp
->int_flags
= (ifs
.if_flags
& 0x1ff) | IFF_INTERFACE
;
/* this works because broadaddr overlaps dstaddr */
ifp
->int_broadaddr
= ifdstaddr
;
* Now arrange for a socket to listen on.
* This nonsense is necessary because of the stupidity
* of the raw socket code.
/* listen on our own address... */
sxn
= (struct sockaddr_xn
*) &ifp
->int_addr
;
sxn
->sxn_addr
.xn_socket
= htons(IDPPORT_RIF
);
ifp
->int_ripsock
[0] = getsocket(AF_XNS
, SOCK_RAW
, IDPPROTO_RIF
, sxn
);
/* AND on our broadcast address if we have one */
if (ifp
->int_flags
& IFF_BROADCAST
) {
sxn
= (struct sockaddr_xn
*) &ifp
->int_broadaddr
;
sxn
->sxn_addr
.xn_socket
= htons(IDPPORT_RIF
);
ifp
->int_ripsock
[1] = getsocket(AF_XNS
, SOCK_RAW
, IDPPROTO_RIF
, sxn
);
if (externalinterfaces
> 1 && supplier
< 0)
for(j
= 3; j
< 32; j
++) close(j
);
execv("/etc/XNSrouted", argv0
);
if (ifp
->int_flags
& IFF_POINTOPOINT
)
bzero(&net
, sizeof (net
));
xnnet(net
.sxn_addr
.xn_net
) = xnnet(((struct sockaddr_xn
*)(&ifp
->int_addr
))->sxn_addr
.xn_net
);
dst
= (struct sockaddr
*)&net
;
rtadd(dst
, &ifp
->int_addr
, ifp
->int_metric
,
ifp
->int_flags
& (IFF_INTERFACE
|IFF_PASSIVE
|IFF_REMOTE
));