* Copyright (c) 1985 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* Includes material written at Cornell University by Bill Nesheim,
* by permission of the author.
static char sccsid
[] = "@(#)input.c 5.5 (Berkeley) %G%";
* XNS Routing Table Management Daemon
static struct sockaddr_ns sxn
;
extern char ether_broadcast_addr
[6];
bzero(&sxn
, sizeof (struct sockaddr_ns
));
xnnet(sxn
.sns_addr
.x_net
) = xnnet(net
[0]);
sxn
.sns_addr
.x_host
= *(union ns_host
*)ether_broadcast_addr
;
return( (struct sockaddr
*)&sxn
);
* Process a newly received packet.
TRACE_INPUT(ifp
, from
, size
);
if (from
->sa_family
>= AF_MAX
)
afp
= &afswitch
[from
->sa_family
];
size
-= sizeof (u_short
) /* command */;
switch (ntohs(msg
->rip_cmd
)) {
if (size
< sizeof (struct netinfo
))
size
-= sizeof (struct netinfo
);
* A single entry with rip_dst == DSTNETS_ALL and
* metric ``infinity'' means ``all routes''.
if (ntohl(xnnet(n
->rip_dst
[0])) == DSTNETS_ALL
&&
ntohs(n
->rip_metric
) == HOPCNT_INFINITY
&&
ifp
= if_ifwithnet(from
);
* request for specific nets
rt
= rtlookup(xns_nettosa(n
->rip_dst
));
"specific request for %d",
ntohl(xnnet(n
->rip_dst
[0])));
n
->rip_metric
= htons( rt
== 0 ? HOPCNT_INFINITY
:
min(rt
->rt_metric
+1, HOPCNT_INFINITY
));
n
++, newsize
+= sizeof (struct netinfo
);
msg
->rip_cmd
= htons(RIPCMD_RESPONSE
);
newsize
+= sizeof (u_short
);
/* should check for if with dstaddr(from) first */
(*afp
->af_output
)(0, from
, newsize
);
(ifp
= if_ifwithnet(from
));
", request arriving on interface %x\n",
/* verify message came from a router */
if ((*afp
->af_portmatch
)(from
) == 0)
/* are we talking to ourselves? */
if (ifp
= if_ifwithaddr(from
)) {
if (rt
== 0 || (rt
->rt_state
& RTS_INTERFACE
) == 0)
/* Update timer for interface on which the packet arrived.
* If from other end of a point-to-point link that isn't
* in the routing tables, (re-)add the route.
if ((rt
= rtfind(from
)) && (rt
->rt_state
& RTS_INTERFACE
)) {
if(ftrace
) fprintf(ftrace
, "Got route\n");
} else if (ifp
= if_ifwithdstaddr(from
)) {
if(ftrace
) fprintf(ftrace
, "Got partner\n");
for (; size
> 0; size
-= sizeof (struct netinfo
), n
++) {
if (size
< sizeof (struct netinfo
))
if ((unsigned) ntohs(n
->rip_metric
) >= HOPCNT_INFINITY
)
rt
= rtfind(sa
= xns_nettosa(n
->rip_dst
));
rtadd(sa
, from
, ntohs(n
->rip_metric
), 0);
* Update if from gateway and different,
* from anywhere and shorter, or getting stale and equivalent.
if ((equal(from
, &rt
->rt_router
) &&
ntohs(n
->rip_metric
) != rt
->rt_metric
) ||
(unsigned) ntohs(n
->rip_metric
) < rt
->rt_metric
||
(rt
->rt_timer
> (EXPIRE_TIME
/2) &&
rt
->rt_metric
== ntohs(n
->rip_metric
))) {
rtchange(rt
, from
, ntohs(n
->rip_metric
));