Remove directory which should not have been re-added.
This commit is contained in:
parent
dda5b39711
commit
9883318f10
@ -1,220 +0,0 @@
|
||||
.\" Copyright (c) 1986, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Copyright (c) 1995 John Hay. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 11, 1995
|
||||
.Dt IPXROUTED 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm IPXrouted
|
||||
.Nd IPX Routing Information Protocol daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl N
|
||||
.Op Fl q
|
||||
.Op Fl s
|
||||
.Op Fl S
|
||||
.Op Fl t
|
||||
.Op Ar logfile
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is invoked at boot time to manage the
|
||||
.Tn IPX
|
||||
routing tables.
|
||||
The
|
||||
.Tn IPX
|
||||
routing daemon uses the Novell
|
||||
.Tn IPX
|
||||
Routing Information Protocol in maintaining up to date kernel routing
|
||||
table entries.
|
||||
.Pp
|
||||
Available options:
|
||||
.Bl -tag -width logfile
|
||||
.It Fl N
|
||||
Do not reply on GetNearestServer
|
||||
.Tn SAP
|
||||
request.
|
||||
.It Fl q
|
||||
Do not supply routing information (opposite of
|
||||
.Fl s
|
||||
option below).
|
||||
.It Fl s
|
||||
Forces
|
||||
.Nm
|
||||
to supply routing information whether it is acting as an internetwork
|
||||
router or not.
|
||||
.It Fl S
|
||||
Do not supply Service Advertising Protocol
|
||||
.Pq Tn SAP
|
||||
information.
|
||||
The default is to supply
|
||||
.Tn SAP
|
||||
information.
|
||||
.It Fl t
|
||||
All packets sent or received are
|
||||
printed on the standard output.
|
||||
In addition,
|
||||
.Nm
|
||||
will not divorce itself from the controlling terminal
|
||||
so that interrupts from the keyboard will kill the process.
|
||||
.It Ar logfile
|
||||
Name of file in which
|
||||
.Nm Ns 's
|
||||
actions should be logged.
|
||||
This log contains information
|
||||
about any changes to the routing tables and a history of
|
||||
recent messages sent and received which are related to
|
||||
the changed route.
|
||||
.El
|
||||
.Pp
|
||||
In normal operation
|
||||
.Nm
|
||||
listens
|
||||
for routing information packets.
|
||||
If the host is connected to
|
||||
multiple
|
||||
.Tn IPX
|
||||
networks, it periodically supplies copies
|
||||
of its routing tables to any directly connected hosts
|
||||
and networks.
|
||||
.Pp
|
||||
When
|
||||
.Nm
|
||||
is started, it uses the
|
||||
.Dv SIOCGIFCONF
|
||||
.Xr ioctl 2
|
||||
to find those
|
||||
directly connected interfaces configured into the
|
||||
system and marked
|
||||
.Dq up
|
||||
(the software loopback interface is ignored).
|
||||
If multiple interfaces
|
||||
are present, it is assumed the host will forward packets
|
||||
between networks.
|
||||
The
|
||||
.Nm
|
||||
utility then transmits a
|
||||
.Em request
|
||||
packet on each interface (using a broadcast packet if
|
||||
the interface supports it) and enters a loop, listening
|
||||
for
|
||||
.Em request
|
||||
and
|
||||
.Em response
|
||||
packets from other hosts.
|
||||
.Pp
|
||||
When a
|
||||
.Em request
|
||||
packet is received,
|
||||
.Nm
|
||||
formulates a reply based on the information maintained in its
|
||||
internal tables.
|
||||
The
|
||||
.Em response
|
||||
packet generated contains a list of known routes, each marked
|
||||
with a
|
||||
.Dq hop count
|
||||
metric (a count of 16, or greater, is
|
||||
considered
|
||||
.Dq infinite ) .
|
||||
The metric associated with each
|
||||
route returned provides a metric
|
||||
.Em relative to the sender .
|
||||
.Pp
|
||||
.Em Response
|
||||
packets received by
|
||||
.Nm
|
||||
are used to update the routing tables if one of the following
|
||||
conditions is satisfied:
|
||||
.Bl -bullet
|
||||
.It
|
||||
No routing table entry exists for the destination network
|
||||
or host, and the metric indicates the destination is
|
||||
.Dq reachable
|
||||
(i.e., the hop count is not infinite).
|
||||
.It
|
||||
The source host of the packet is the same as the router in the
|
||||
existing routing table entry.
|
||||
That is, updated information is
|
||||
being received from the very internetwork router through which
|
||||
packets for the destination are being routed.
|
||||
.It
|
||||
The existing entry in the routing table has not been updated for
|
||||
some time (defined to be 90 seconds) and the route is at least
|
||||
as cost effective as the current route.
|
||||
.It
|
||||
The new route describes a shorter route to the destination than
|
||||
the one currently stored in the routing tables; the metric of
|
||||
the new route is compared against the one stored in the table
|
||||
to decide this.
|
||||
.El
|
||||
.Pp
|
||||
When an update is applied,
|
||||
.Nm
|
||||
records the change in its internal tables and generates a
|
||||
.Em response
|
||||
packet to all directly connected hosts and networks.
|
||||
The
|
||||
.Xr routed 8
|
||||
utility waits a short period
|
||||
of time (no more than 30 seconds) before modifying the kernel's
|
||||
routing tables to allow possible unstable situations to settle.
|
||||
.Pp
|
||||
In addition to processing incoming packets,
|
||||
.Nm
|
||||
also periodically checks the routing table entries.
|
||||
If an entry has not been updated for 3 minutes, the entry's metric
|
||||
is set to infinity and marked for deletion.
|
||||
Deletions are delayed
|
||||
an additional 60 seconds to ensure the invalidation is propagated
|
||||
to other routers.
|
||||
.Pp
|
||||
Hosts acting as internetwork routers gratuitously supply their
|
||||
routing tables every 30 seconds to all directly connected hosts
|
||||
and networks.
|
||||
.Pp
|
||||
If
|
||||
.Nm
|
||||
receives a
|
||||
.Dv SIGINFO
|
||||
signal the current contents of the
|
||||
.Tn RIP
|
||||
and
|
||||
.Tn SAP
|
||||
tables are appended to the file
|
||||
.Pa /var/log/ipxrouted.dmp .
|
||||
.Sh SEE ALSO
|
||||
.Xr ipx 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Fx 2.2 .
|
@ -1,11 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= IPXrouted
|
||||
MAN= IPXrouted.8
|
||||
SRCS= af.c if.c input.c main.c output.c startup.c tables.c timer.c trace.c
|
||||
SRCS+= sap_input.c sap_tables.c sap_output.c
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)af.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
/*
|
||||
* Address family support routines
|
||||
*/
|
||||
af_hash_t null_hash;
|
||||
af_netmatch_t null_netmatch;
|
||||
af_output_t null_output;
|
||||
af_portmatch_t null_portmatch;
|
||||
af_portcheck_t null_portcheck;
|
||||
af_checkhost_t null_checkhost;
|
||||
af_ishost_t null_ishost;
|
||||
af_canon_t null_canon;
|
||||
|
||||
void ipxnet_hash(struct sockaddr_ipx *, struct afhash *);
|
||||
int ipxnet_netmatch(struct sockaddr_ipx *, struct sockaddr_ipx *);
|
||||
void ipxnet_output(int, int, struct sockaddr_ipx *, int);
|
||||
int ipxnet_portmatch(struct sockaddr_ipx *);
|
||||
int ipxnet_checkhost(struct sockaddr_ipx *);
|
||||
int ipxnet_ishost(struct sockaddr_ipx *);
|
||||
void ipxnet_canon(struct sockaddr_ipx *);
|
||||
|
||||
#define NIL \
|
||||
{ null_hash, null_netmatch, null_output, \
|
||||
null_portmatch, null_portcheck, null_checkhost, \
|
||||
null_ishost, null_canon }
|
||||
#define IPXNET \
|
||||
{ (af_hash_t *)ipxnet_hash, \
|
||||
(af_netmatch_t *)ipxnet_netmatch, \
|
||||
(af_output_t *)ipxnet_output, \
|
||||
(af_portmatch_t *)ipxnet_portmatch, \
|
||||
(af_portcheck_t *)ipxnet_portmatch, \
|
||||
(af_checkhost_t *)ipxnet_checkhost, \
|
||||
(af_ishost_t *)ipxnet_ishost, \
|
||||
(af_canon_t *)ipxnet_canon }
|
||||
|
||||
struct afswitch afswitch[AF_MAX] =
|
||||
{ NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
|
||||
NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
|
||||
NIL, NIL, NIL, IPXNET, NIL, NIL };
|
||||
|
||||
struct sockaddr_ipx ipxnet_default = { sizeof(struct sockaddr_ipx), AF_IPX };
|
||||
|
||||
union ipx_net ipx_anynet;
|
||||
union ipx_net ipx_zeronet;
|
||||
|
||||
void
|
||||
ipxnet_hash(sipx, hp)
|
||||
register struct sockaddr_ipx *sipx;
|
||||
struct afhash *hp;
|
||||
{
|
||||
long hash;
|
||||
#if 0
|
||||
u_short *s = sipx->sipx_addr.x_host.s_host;
|
||||
#endif
|
||||
u_char *c;
|
||||
|
||||
c = sipx->sipx_addr.x_net.c_net;
|
||||
|
||||
#define IMVAL 33
|
||||
hash = 0;
|
||||
hash = hash * IMVAL + *c++;
|
||||
hash = hash * IMVAL + *c++;
|
||||
hash = hash * IMVAL + *c++;
|
||||
hash = hash * IMVAL + *c++;
|
||||
#undef IMVAL
|
||||
|
||||
hp->afh_nethash = hash;
|
||||
hp->afh_nethash ^= (hash >> 8);
|
||||
hp->afh_nethash ^= (hash >> 16);
|
||||
hp->afh_nethash ^= (hash >> 24);
|
||||
|
||||
#if 0
|
||||
hash = 0;
|
||||
hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
|
||||
hp->afh_hosthash = hash;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
ipxnet_netmatch(sxn1, sxn2)
|
||||
struct sockaddr_ipx *sxn1, *sxn2;
|
||||
{
|
||||
return (ipx_neteq(sxn1->sipx_addr, sxn2->sipx_addr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the message is from the right port.
|
||||
*/
|
||||
int
|
||||
ipxnet_portmatch(sipx)
|
||||
register struct sockaddr_ipx *sipx;
|
||||
{
|
||||
|
||||
return (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ipx output routine.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
int do_output = 0;
|
||||
#endif
|
||||
void
|
||||
ipxnet_output(s, flags, sipx, size)
|
||||
int s;
|
||||
int flags;
|
||||
struct sockaddr_ipx *sipx;
|
||||
int size;
|
||||
{
|
||||
struct sockaddr_ipx dst;
|
||||
|
||||
dst = *sipx;
|
||||
sipx = &dst;
|
||||
if (sipx->sipx_addr.x_port == 0)
|
||||
sipx->sipx_addr.x_port = htons(IPXPORT_RIP);
|
||||
#ifdef DEBUG
|
||||
if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST)
|
||||
#endif
|
||||
/*
|
||||
* Kludge to allow us to get routes out to machines that
|
||||
* don't know their addresses yet; send to that address on
|
||||
* ALL connected nets
|
||||
*/
|
||||
if (ipx_neteqnn(sipx->sipx_addr.x_net, ipx_zeronet)) {
|
||||
extern struct interface *ifnet;
|
||||
register struct interface *ifp;
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
sipx->sipx_addr.x_net =
|
||||
satoipx_addr(ifp->int_addr).x_net;
|
||||
(void) sendto(s, msg, size, flags,
|
||||
(struct sockaddr *)sipx, sizeof (*sipx));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
(void) sendto(s, msg, size, flags,
|
||||
(struct sockaddr *)sipx, sizeof (*sipx));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 1 if we want this route.
|
||||
* We use this to disallow route net G entries for one for multiple
|
||||
* point to point links.
|
||||
*/
|
||||
int
|
||||
ipxnet_checkhost(sipx)
|
||||
struct sockaddr_ipx *sipx;
|
||||
{
|
||||
register struct interface *ifp = if_ifwithnet((struct sockaddr *)sipx);
|
||||
/*
|
||||
* We want this route if there is no more than one
|
||||
* point to point interface with this network.
|
||||
*/
|
||||
if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1);
|
||||
return (ifp->int_sq.n == ifp->int_sq.p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 1 if the address is
|
||||
* for a host, 0 for a network.
|
||||
*/
|
||||
int
|
||||
ipxnet_ishost(sipx)
|
||||
struct sockaddr_ipx *sipx;
|
||||
{
|
||||
register u_short *s = sipx->sipx_addr.x_host.s_host;
|
||||
|
||||
if ((s[0]==0x0000) && (s[1]==0x0000) && (s[2]==0x0000))
|
||||
return (0);
|
||||
if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ipxnet_canon(sipx)
|
||||
struct sockaddr_ipx *sipx;
|
||||
{
|
||||
|
||||
sipx->sipx_addr.x_port = 0;
|
||||
}
|
||||
|
||||
void
|
||||
null_hash(addr, hp)
|
||||
struct sockaddr *addr;
|
||||
struct afhash *hp;
|
||||
{
|
||||
|
||||
hp->afh_nethash = hp->afh_hosthash = 0;
|
||||
}
|
||||
|
||||
int
|
||||
null_netmatch(a1, a2)
|
||||
struct sockaddr *a1, *a2;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
null_output(s, f, a1, n)
|
||||
int s;
|
||||
int f;
|
||||
struct sockaddr *a1;
|
||||
int n;
|
||||
{
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
int
|
||||
null_portmatch(a1)
|
||||
struct sockaddr *a1;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
null_portcheck(a1)
|
||||
struct sockaddr *a1;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
null_ishost(a1)
|
||||
struct sockaddr *a1;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
null_checkhost(a1)
|
||||
struct sockaddr *a1;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
null_canon(a1)
|
||||
struct sockaddr *a1;
|
||||
{
|
||||
|
||||
;
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)af.h 5.1 (Berkeley) 6/4/85 (routed/af.h)
|
||||
*
|
||||
* @(#)af.h 8.1 (Berkeley) 6/5/93
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routing table management daemon.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure returned by af_hash routines.
|
||||
*/
|
||||
struct afhash {
|
||||
u_int afh_hosthash; /* host based hash */
|
||||
u_int afh_nethash; /* network based hash */
|
||||
};
|
||||
|
||||
/*
|
||||
* Per address family routines.
|
||||
*/
|
||||
typedef void af_hash_t(struct sockaddr *, struct afhash *);
|
||||
typedef int af_netmatch_t(struct sockaddr *, struct sockaddr *);
|
||||
typedef void af_output_t(int, int, struct sockaddr *, int);
|
||||
typedef int af_portmatch_t(struct sockaddr *);
|
||||
typedef int af_portcheck_t(struct sockaddr *);
|
||||
typedef int af_checkhost_t(struct sockaddr *);
|
||||
typedef int af_ishost_t(struct sockaddr *);
|
||||
typedef void af_canon_t(struct sockaddr *);
|
||||
|
||||
struct afswitch {
|
||||
af_hash_t *af_hash; /* returns keys based on address */
|
||||
af_netmatch_t *af_netmatch; /* verifies net # matching */
|
||||
af_output_t *af_output; /* interprets address for sending */
|
||||
af_portmatch_t *af_portmatch; /* packet from some other router? */
|
||||
af_portcheck_t *af_portcheck; /* packet from privileged peer? */
|
||||
af_checkhost_t *af_checkhost; /* tells if address for host or net */
|
||||
af_ishost_t *af_ishost; /* tells if address is valid */
|
||||
af_canon_t *af_canon; /* canonicalize address for compares */
|
||||
};
|
||||
|
||||
struct afswitch afswitch[AF_MAX]; /* table proper */
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)defs.h 8.1 (Berkeley) 6/5/93
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/route.h>
|
||||
#include <netipx/ipx.h>
|
||||
#if defined(vax) || defined(pdp11)
|
||||
#define xnnet(x) ((u_long) (x)->rip_dst[1] << 16 | (u_long) (x)->rip_dst[0] )
|
||||
#else
|
||||
#define xnnet(x) ((u_long) (x)->rip_dst[0] << 16 | (u_long) (x)->rip_dst[1] )
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "protocol.h"
|
||||
#include "sap.h"
|
||||
#include "table.h"
|
||||
#include "trace.h"
|
||||
#include "interface.h"
|
||||
#include "af.h"
|
||||
|
||||
|
||||
/*
|
||||
* When we find any interfaces marked down we rescan the
|
||||
* kernel every CHECK_INTERVAL seconds to see if they've
|
||||
* come up.
|
||||
*/
|
||||
#define CHECK_INTERVAL (5*60)
|
||||
|
||||
#define equal(a1, a2) \
|
||||
(bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof (struct sockaddr)) == 0)
|
||||
#define min(a,b) ((a)>(b)?(b):(a))
|
||||
#define max(a,b) ((a)<(b)?(b):(a))
|
||||
|
||||
extern int ripsock; /* Socket to listen on */
|
||||
extern int sapsock; /* Socket to listen on */
|
||||
extern int kmem;
|
||||
extern int supplier; /* process should supply updates */
|
||||
extern int dosap; /* SAP is enabled */
|
||||
extern int dognreply; /* enable GET_NEAREST response */
|
||||
extern int install; /* if 1 call kernel */
|
||||
extern int lookforinterfaces; /* if 1 probe kernel for new up ifs */
|
||||
extern int performnlist; /* if 1 check if /kernel has changed */
|
||||
extern int externalinterfaces; /* # of remote and local interfaces */
|
||||
extern int timeval; /* local idea of time */
|
||||
extern int noteremoterequests; /* squawk on requests from non-local nets */
|
||||
extern int r; /* Routing socket to install updates with */
|
||||
extern int gateway;
|
||||
extern struct sockaddr_ipx ipx_netmask; /* Used in installing routes */
|
||||
|
||||
extern char packet[MAXRXPACKETSIZE+1];
|
||||
extern struct rip *msg;
|
||||
|
||||
extern char **argv0;
|
||||
|
||||
#define ADD 1
|
||||
#define DELETE 2
|
||||
#define CHANGE 3
|
||||
|
||||
void sndmsg(struct sockaddr *, int, struct interface *, int);
|
||||
void supply(struct sockaddr *, int, struct interface *, int);
|
||||
void addrouteforif(struct interface *);
|
||||
void ifinit(void);
|
||||
void toall(void (*f)(struct sockaddr *, int, struct interface *, int),
|
||||
struct rt_entry *, int);
|
||||
void rip_input(struct sockaddr *, int);
|
||||
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* static char sccsid[] = "@(#)if.c 5.1 (Berkeley) 6/4/85"; (routed/if.c)
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
|
||||
extern struct interface *ifnet;
|
||||
|
||||
/*
|
||||
* Find the interface with address addr.
|
||||
*/
|
||||
struct interface *
|
||||
if_ifwithaddr(addr)
|
||||
struct sockaddr *addr;
|
||||
{
|
||||
register struct interface *ifp;
|
||||
|
||||
#define same(a1, a2) \
|
||||
(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 10) == 0)
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
if (ifp->int_flags & IFF_REMOTE)
|
||||
continue;
|
||||
if (ifp->int_addr.sa_family != addr->sa_family)
|
||||
continue;
|
||||
if (same(&ifp->int_addr, addr))
|
||||
break;
|
||||
if ((ifp->int_flags & IFF_BROADCAST) &&
|
||||
same(&ifp->int_broadaddr, addr))
|
||||
break;
|
||||
}
|
||||
return (ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the point-to-point interface with destination address addr.
|
||||
*/
|
||||
struct interface *
|
||||
if_ifwithdstaddr(addr)
|
||||
struct sockaddr *addr;
|
||||
{
|
||||
register struct interface *ifp;
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
|
||||
continue;
|
||||
if (same(&ifp->int_dstaddr, addr))
|
||||
break;
|
||||
}
|
||||
return (ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the interface on the network
|
||||
* of the specified address.
|
||||
*/
|
||||
struct interface *
|
||||
if_ifwithnet(addr)
|
||||
register struct sockaddr *addr;
|
||||
{
|
||||
register struct interface *ifp;
|
||||
register int af = addr->sa_family;
|
||||
register int (*netmatch)();
|
||||
|
||||
if (af >= AF_MAX)
|
||||
return (0);
|
||||
netmatch = afswitch[af].af_netmatch;
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
if (ifp->int_flags & IFF_REMOTE)
|
||||
continue;
|
||||
if (af != ifp->int_addr.sa_family)
|
||||
continue;
|
||||
if ((*netmatch)(addr, &ifp->int_addr))
|
||||
break;
|
||||
}
|
||||
return (ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an interface from which the specified address
|
||||
* should have come from. Used for figuring out which
|
||||
* interface a packet came in on -- for tracing.
|
||||
*/
|
||||
struct interface *
|
||||
if_iflookup(addr)
|
||||
struct sockaddr *addr;
|
||||
{
|
||||
register struct interface *ifp, *maybe;
|
||||
register int af = addr->sa_family;
|
||||
register int (*netmatch)();
|
||||
|
||||
if (af >= AF_MAX)
|
||||
return (0);
|
||||
maybe = 0;
|
||||
netmatch = afswitch[af].af_netmatch;
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
if (ifp->int_addr.sa_family != af)
|
||||
continue;
|
||||
if (same(&ifp->int_addr, addr))
|
||||
break;
|
||||
if ((ifp->int_flags & IFF_BROADCAST) &&
|
||||
same(&ifp->int_broadaddr, addr))
|
||||
break;
|
||||
if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr))
|
||||
maybe = ifp;
|
||||
}
|
||||
if (ifp == 0)
|
||||
ifp = maybe;
|
||||
return (ifp);
|
||||
}
|
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* IPX Routing Table Management Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
|
||||
struct sockaddr *
|
||||
ipx_nettosa(net)
|
||||
union ipx_net net;
|
||||
{
|
||||
static struct sockaddr_ipx sxn;
|
||||
|
||||
bzero(&sxn, sizeof (struct sockaddr_ipx));
|
||||
sxn.sipx_family = AF_IPX;
|
||||
sxn.sipx_len = sizeof (sxn);
|
||||
sxn.sipx_addr.x_net = net;
|
||||
return( (struct sockaddr *)&sxn);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a newly received packet.
|
||||
*/
|
||||
void
|
||||
rip_input(from, size)
|
||||
struct sockaddr *from;
|
||||
int size;
|
||||
{
|
||||
int newsize;
|
||||
int rtchanged = 0;
|
||||
struct rt_entry *rt;
|
||||
struct netinfo *n;
|
||||
struct interface *ifp = 0;
|
||||
struct afswitch *afp;
|
||||
struct sockaddr_ipx *ipxp;
|
||||
|
||||
ifp = if_ifwithnet(from);
|
||||
ipxp = (struct sockaddr_ipx *)from;
|
||||
if (ifp == 0) {
|
||||
if(ftrace) {
|
||||
fprintf(ftrace, "Received bogus packet from %s\n",
|
||||
ipxdp_ntoa(&ipxp->sipx_addr));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_INPUT(ifp, from, size);
|
||||
if (from->sa_family >= AF_MAX)
|
||||
return;
|
||||
afp = &afswitch[from->sa_family];
|
||||
|
||||
size -= sizeof (u_short) /* command */;
|
||||
n = msg->rip_nets;
|
||||
|
||||
switch (ntohs(msg->rip_cmd)) {
|
||||
|
||||
case RIPCMD_REQUEST:
|
||||
if (ipx_hosteq(satoipx_addr(ifp->int_addr), ipxp->sipx_addr))
|
||||
return;
|
||||
newsize = 0;
|
||||
while (size > 0) {
|
||||
if (size < sizeof (struct netinfo))
|
||||
break;
|
||||
size -= sizeof (struct netinfo);
|
||||
|
||||
/*
|
||||
* A single entry with rip_dst == DSTNETS_ALL and
|
||||
* metric ``infinity'' means ``all routes''.
|
||||
*
|
||||
* XXX According to the IPX RIP spec the metric
|
||||
* and tick fields can be anything. So maybe we
|
||||
* should not check the metric???
|
||||
*/
|
||||
if (ipx_neteqnn(n->rip_dst, ipx_anynet) &&
|
||||
ntohs(n->rip_metric) == HOPCNT_INFINITY &&
|
||||
size == 0) {
|
||||
supply(from, 0, ifp, 0);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* request for specific nets
|
||||
*/
|
||||
rt = rtlookup(ipx_nettosa(n->rip_dst));
|
||||
if (ftrace) {
|
||||
fprintf(ftrace,
|
||||
"specific request for %s",
|
||||
ipxdp_nettoa(n->rip_dst));
|
||||
fprintf(ftrace,
|
||||
" yields route %lx\n",
|
||||
(u_long)rt);
|
||||
}
|
||||
/*
|
||||
* XXX We break out on the first net that isn't
|
||||
* found. The specs is a bit vague here. I'm not
|
||||
* sure what we should do.
|
||||
*/
|
||||
if (rt == 0)
|
||||
return;
|
||||
/* XXX
|
||||
* According to the spec we should not include
|
||||
* information about networks for which the number
|
||||
* of hops is 16.
|
||||
*/
|
||||
if (rt->rt_metric == (HOPCNT_INFINITY-1))
|
||||
return;
|
||||
n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY :
|
||||
min(rt->rt_metric+1, HOPCNT_INFINITY));
|
||||
n->rip_ticks = htons(rt->rt_ticks+1);
|
||||
|
||||
/*
|
||||
* We use split horizon with a twist. If the requested
|
||||
* net is the directly connected net we supply an
|
||||
* answer. This is so that the host can learn about
|
||||
* the routers on its net.
|
||||
*/
|
||||
{
|
||||
register struct rt_entry *trt = rt;
|
||||
|
||||
while (trt) {
|
||||
if ((trt->rt_ifp == ifp) &&
|
||||
!ipx_neteqnn(n->rip_dst,
|
||||
satoipx_addr(ifp->int_addr).x_net))
|
||||
return;
|
||||
trt = trt->rt_clone;
|
||||
}
|
||||
n++;
|
||||
newsize += sizeof (struct netinfo);
|
||||
}
|
||||
}
|
||||
if (newsize > 0) {
|
||||
msg->rip_cmd = htons(RIPCMD_RESPONSE);
|
||||
newsize += sizeof (u_short);
|
||||
/* should check for if with dstaddr(from) first */
|
||||
(*afp->af_output)(ripsock, 0, from, newsize);
|
||||
TRACE_OUTPUT(ifp, from, newsize);
|
||||
if (ftrace) {
|
||||
/* XXX This should not happen anymore. */
|
||||
if(ifp == 0)
|
||||
fprintf(ftrace, "--- ifp = 0\n");
|
||||
else
|
||||
fprintf(ftrace,
|
||||
"request arrived on interface %s\n",
|
||||
ifp->int_name);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case RIPCMD_RESPONSE:
|
||||
/* verify message came from a router */
|
||||
if ((*afp->af_portmatch)(from) == 0)
|
||||
return;
|
||||
(*afp->af_canon)(from);
|
||||
/* are we talking to ourselves? */
|
||||
if ((ifp = if_ifwithaddr(from)) != 0) {
|
||||
rt = rtfind(from);
|
||||
if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0) {
|
||||
addrouteforif(ifp);
|
||||
rtchanged = 1;
|
||||
} else
|
||||
rt->rt_timer = 0;
|
||||
return;
|
||||
}
|
||||
/* 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");
|
||||
rt->rt_timer = 0;
|
||||
} else if ((ifp = if_ifwithdstaddr(from)) != 0) {
|
||||
if(ftrace) fprintf(ftrace, "Got partner\n");
|
||||
addrouteforif(ifp);
|
||||
rtchanged = 1;
|
||||
}
|
||||
for (; size > 0; size -= sizeof (struct netinfo), n++) {
|
||||
struct sockaddr *sa;
|
||||
if (size < sizeof (struct netinfo))
|
||||
break;
|
||||
if ((unsigned) ntohs(n->rip_metric) > HOPCNT_INFINITY)
|
||||
continue;
|
||||
rt = rtfind(sa = ipx_nettosa(n->rip_dst));
|
||||
if (rt == 0) {
|
||||
if (ntohs(n->rip_metric) == HOPCNT_INFINITY)
|
||||
continue;
|
||||
rtadd(sa, from, ntohs(n->rip_metric),
|
||||
ntohs(n->rip_ticks), 0);
|
||||
rtchanged = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* A clone is a different route to the same net
|
||||
* with exactly the same cost (ticks and metric).
|
||||
* They must all be recorded because those interfaces
|
||||
* must be handled in the same way as the first route
|
||||
* to that net. ie When using the split horizon
|
||||
* algorithm we must look at these interfaces also.
|
||||
*
|
||||
* Update if from gateway and different,
|
||||
* from anywhere and less ticks or
|
||||
* if same ticks and shorter,
|
||||
* or getting stale and equivalent.
|
||||
*/
|
||||
if (!equal(from, &rt->rt_router) &&
|
||||
ntohs(n->rip_ticks) == rt->rt_ticks &&
|
||||
ntohs(n->rip_metric) == rt->rt_metric &&
|
||||
ntohs(n->rip_metric) != HOPCNT_INFINITY) {
|
||||
register struct rt_entry *trt = rt->rt_clone;
|
||||
|
||||
while (trt) {
|
||||
if (equal(from, &trt->rt_router)) {
|
||||
trt->rt_timer = 0;
|
||||
break;
|
||||
}
|
||||
trt = trt->rt_clone;
|
||||
}
|
||||
if (trt == NULL) {
|
||||
rtadd_clone(rt, sa, from,
|
||||
ntohs(n->rip_metric),
|
||||
ntohs(n->rip_ticks), 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((equal(from, &rt->rt_router) &&
|
||||
((ntohs(n->rip_ticks) != rt->rt_ticks) ||
|
||||
(ntohs(n->rip_metric) != rt->rt_metric))) ||
|
||||
(ntohs(n->rip_ticks) < rt->rt_ticks) ||
|
||||
((ntohs(n->rip_ticks) == rt->rt_ticks) &&
|
||||
(ntohs(n->rip_metric) < rt->rt_metric)) ||
|
||||
(rt->rt_timer > (EXPIRE_TIME*2/3) &&
|
||||
rt->rt_metric == ntohs(n->rip_metric) &&
|
||||
ntohs(n->rip_metric) != HOPCNT_INFINITY)) {
|
||||
rtchange(rt, from, ntohs(n->rip_metric),
|
||||
ntohs(n->rip_ticks));
|
||||
if (ntohs(n->rip_metric) == HOPCNT_INFINITY)
|
||||
rt->rt_timer = EXPIRE_TIME;
|
||||
else
|
||||
rt->rt_timer = 0;
|
||||
rtchanged = 1;
|
||||
} else if (equal(from, &rt->rt_router) &&
|
||||
(ntohs(n->rip_ticks) == rt->rt_ticks) &&
|
||||
(ntohs(n->rip_metric) == rt->rt_metric) &&
|
||||
(ntohs(n->rip_metric) != HOPCNT_INFINITY)) {
|
||||
rt->rt_timer = 0;
|
||||
}
|
||||
}
|
||||
if (rtchanged) {
|
||||
register struct rthash *rh;
|
||||
register struct rt_entry *rt;
|
||||
|
||||
toall(supply, NULL, 1);
|
||||
for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)
|
||||
for (rt = rh->rt_forw;
|
||||
rt != (struct rt_entry *)rh;
|
||||
rt = rt->rt_forw)
|
||||
rt->rt_state &= ~RTS_CHANGED;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)interface.h 8.1 (Berkeley) 6/5/93
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routing table management daemon.
|
||||
*/
|
||||
|
||||
/*
|
||||
* An ``interface'' is similar to an ifnet structure,
|
||||
* except it doesn't contain q'ing info, and it also
|
||||
* handles ``logical'' interfaces (remote gateways
|
||||
* that we want to keep polling even if they go down).
|
||||
* The list of interfaces which we maintain is used
|
||||
* in supplying the gratuitous routing table updates.
|
||||
* We list only one address for each interface, the AF_IPX one.
|
||||
*/
|
||||
struct interface {
|
||||
struct interface *int_next;
|
||||
struct sockaddr int_addr; /* address on this host */
|
||||
union {
|
||||
struct sockaddr intu_broadaddr;
|
||||
struct sockaddr intu_dstaddr;
|
||||
} int_intu;
|
||||
#define int_broadaddr int_intu.intu_broadaddr /* broadcast address */
|
||||
#define int_dstaddr int_intu.intu_dstaddr /* other end of p-to-p link */
|
||||
int int_metric; /* init's routing entry */
|
||||
int int_flags; /* see below */
|
||||
struct ifdebug int_input, int_output; /* packet tracing stuff */
|
||||
int int_ipackets; /* input packets received */
|
||||
int int_opackets; /* output packets sent */
|
||||
char *int_name; /* from kernel if structure */
|
||||
u_short int_transitions; /* times gone up-down */
|
||||
|
||||
/* XXX IPX Specific entry */
|
||||
struct sameq {
|
||||
struct sameq *n; /* q of other pt-to-pt links */
|
||||
struct sameq *p; /* with same net # */
|
||||
} int_sq;
|
||||
};
|
||||
|
||||
/*
|
||||
* 0x1 to 0x10 are reused from the kernel's ifnet definitions,
|
||||
* the others agree with the RTS_ flags defined elsewhere.
|
||||
*/
|
||||
#define IFF_UP 0x1 /* interface is up */
|
||||
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||
#define IFF_DEBUG 0x4 /* turn on debugging */
|
||||
#define IFF_ROUTE 0x8 /* routing entry installed */
|
||||
#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
|
||||
|
||||
#define IFF_PASSIVE 0x200000 /* can't tell if up/down */
|
||||
#define IFF_INTERFACE 0x400000 /* hardware interface */
|
||||
#define IFF_REMOTE 0x800000 /* interface isn't on this machine */
|
||||
|
||||
struct interface *if_ifwithaddr(struct sockaddr *);
|
||||
struct interface *if_ifwithdstaddr(struct sockaddr *);
|
||||
struct interface *if_ifwithnet(struct sockaddr *);
|
||||
struct interface *if_iflookup(struct sockaddr *);
|
||||
|
@ -1,401 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1985, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* IPX Routing Information Protocol Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <nlist.h>
|
||||
#include <signal.h>
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SAP_PKT 0
|
||||
#define RIP_PKT 1
|
||||
|
||||
struct sockaddr_ipx addr; /* Daemon's Address */
|
||||
int ripsock; /* RIP Socket to listen on */
|
||||
int sapsock; /* SAP Socket to listen on */
|
||||
int kmem;
|
||||
int install; /* if 1 call kernel */
|
||||
int lookforinterfaces; /* if 1 probe kernel for new up interfaces */
|
||||
int performnlist; /* if 1 check if /kernel has changed */
|
||||
int externalinterfaces; /* # of remote and local interfaces */
|
||||
int timeval; /* local idea of time */
|
||||
int noteremoterequests; /* squawk on requests from non-local nets */
|
||||
int r; /* Routing socket to install updates with */
|
||||
struct sockaddr_ipx ipx_netmask; /* Used in installing routes */
|
||||
|
||||
char packet[MAXRXPACKETSIZE+1];
|
||||
|
||||
char **argv0;
|
||||
|
||||
int supplier = -1; /* process should supply updates */
|
||||
int dosap = 1; /* By default do SAP services. */
|
||||
int dobcast = 1; /* A RIP/SAP broadcast is needed. */
|
||||
time_t lastbcast; /* Time of last RIP/SAP broadcast */
|
||||
|
||||
struct rip *msg = (struct rip *) &packet[sizeof (struct ipx)];
|
||||
struct sap_packet *sap_msg =
|
||||
(struct sap_packet *) &packet[sizeof (struct ipx)];
|
||||
void hup(), fkexit(), timer();
|
||||
void process(int fd, int pkt_type);
|
||||
int getsocket(int type, int proto, struct sockaddr_ipx *sipx);
|
||||
void getinfo();
|
||||
void catchtimer();
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int nfds;
|
||||
fd_set fdvar;
|
||||
time_t ttime;
|
||||
struct itimerval tval;
|
||||
|
||||
argv0 = argv;
|
||||
argv++, argc--;
|
||||
while (argc > 0 && **argv == '-') {
|
||||
if (strcmp(*argv, "-s") == 0) {
|
||||
supplier = 1;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-q") == 0) {
|
||||
supplier = 0;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-R") == 0) {
|
||||
noteremoterequests++;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-S") == 0) {
|
||||
dosap = 0;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-t") == 0) {
|
||||
tracepackets++;
|
||||
argv++, argc--;
|
||||
ftrace = stderr;
|
||||
tracing = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-g") == 0) {
|
||||
gateway = 1;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-l") == 0) {
|
||||
gateway = -1;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(*argv, "-N") == 0) {
|
||||
dognreply = 0;
|
||||
argv++, argc--;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N ]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
#ifndef DEBUG
|
||||
if (!tracepackets)
|
||||
daemon(0, 0);
|
||||
#endif
|
||||
openlog("IPXrouted", LOG_PID, LOG_DAEMON);
|
||||
|
||||
addr.sipx_family = AF_IPX;
|
||||
addr.sipx_len = sizeof(addr);
|
||||
addr.sipx_port = htons(IPXPORT_RIP);
|
||||
ipx_anynet.s_net[0] = ipx_anynet.s_net[1] = -1;
|
||||
ipx_netmask.sipx_addr.x_net = ipx_anynet;
|
||||
ipx_netmask.sipx_len = 6;
|
||||
ipx_netmask.sipx_family = AF_IPX;
|
||||
r = socket(AF_ROUTE, SOCK_RAW, 0);
|
||||
/* later, get smart about lookingforinterfaces */
|
||||
if (r)
|
||||
shutdown(r, SHUT_RD); /* for now, don't want reponses */
|
||||
else {
|
||||
fprintf(stderr, "IPXrouted: no routing socket\n");
|
||||
exit(1);
|
||||
}
|
||||
ripsock = getsocket(SOCK_DGRAM, 0, &addr);
|
||||
if (ripsock < 0)
|
||||
exit(1);
|
||||
|
||||
if (dosap) {
|
||||
addr.sipx_port = htons(IPXPORT_SAP);
|
||||
sapsock = getsocket(SOCK_DGRAM, 0, &addr);
|
||||
if (sapsock < 0)
|
||||
exit(1);
|
||||
} else
|
||||
sapsock = -1;
|
||||
|
||||
/*
|
||||
* Any extra argument is considered
|
||||
* a tracing log file.
|
||||
*/
|
||||
if (argc > 0)
|
||||
traceon(*argv);
|
||||
/*
|
||||
* Collect an initial view of the world by
|
||||
* snooping in the kernel. Then, send a request packet on all
|
||||
* directly connected networks to find out what
|
||||
* everyone else thinks.
|
||||
*/
|
||||
rtinit();
|
||||
sapinit();
|
||||
ifinit();
|
||||
if (supplier < 0)
|
||||
supplier = 0;
|
||||
/* request the state of the world */
|
||||
msg->rip_cmd = htons(RIPCMD_REQUEST);
|
||||
msg->rip_nets[0].rip_dst = ipx_anynet;
|
||||
msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
|
||||
msg->rip_nets[0].rip_ticks = htons(-1);
|
||||
toall(sndmsg, NULL, 0);
|
||||
|
||||
if (dosap) {
|
||||
sap_msg->sap_cmd = htons(SAP_REQ);
|
||||
sap_msg->sap[0].ServType = htons(SAP_WILDCARD);
|
||||
toall(sapsndmsg, NULL, 0);
|
||||
}
|
||||
|
||||
signal(SIGALRM, catchtimer);
|
||||
signal(SIGHUP, hup);
|
||||
signal(SIGINT, hup);
|
||||
signal(SIGEMT, fkexit);
|
||||
signal(SIGINFO, getinfo);
|
||||
|
||||
tval.it_interval.tv_sec = TIMER_RATE;
|
||||
tval.it_interval.tv_usec = 0;
|
||||
tval.it_value.tv_sec = TIMER_RATE;
|
||||
tval.it_value.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &tval, NULL);
|
||||
|
||||
nfds = 1 + max(sapsock, ripsock);
|
||||
|
||||
for (;;) {
|
||||
if (dobcast) {
|
||||
dobcast = 0;
|
||||
lastbcast = time(NULL);
|
||||
timer();
|
||||
}
|
||||
|
||||
FD_ZERO(&fdvar);
|
||||
if (dosap) {
|
||||
FD_SET(sapsock, &fdvar);
|
||||
}
|
||||
FD_SET(ripsock, &fdvar);
|
||||
|
||||
if(select(nfds, &fdvar, (fd_set *)NULL, (fd_set *)NULL,
|
||||
(struct timeval *)NULL) < 0) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
perror("during select");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(FD_ISSET(ripsock, &fdvar))
|
||||
process(ripsock, RIP_PKT);
|
||||
|
||||
if(dosap && FD_ISSET(sapsock, &fdvar))
|
||||
process(sapsock, SAP_PKT);
|
||||
|
||||
ttime = time(NULL);
|
||||
if (ttime > (lastbcast + TIMER_RATE + (TIMER_RATE * 2 / 3))) {
|
||||
dobcast = 1;
|
||||
syslog(LOG_ERR, "Missed alarm");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
process(fd, pkt_type)
|
||||
int fd;
|
||||
int pkt_type;
|
||||
{
|
||||
struct sockaddr from;
|
||||
int cc, omask;
|
||||
socklen_t fromlen = sizeof (from);
|
||||
struct ipx *ipxdp = (struct ipx *)packet;
|
||||
|
||||
cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
|
||||
if (cc <= 0) {
|
||||
if (cc < 0 && errno != EINTR)
|
||||
syslog(LOG_ERR, "recvfrom: %m");
|
||||
return;
|
||||
}
|
||||
if (tracepackets > 1 && ftrace) {
|
||||
fprintf(ftrace,"rcv %d bytes on %s ",
|
||||
cc, ipxdp_ntoa(&ipxdp->ipx_dna));
|
||||
fprintf(ftrace," from %s\n", ipxdp_ntoa(&ipxdp->ipx_sna));
|
||||
}
|
||||
|
||||
if (noteremoterequests &&
|
||||
!ipx_neteqnn(ipxdp->ipx_sna.x_net, ipx_zeronet) &&
|
||||
!ipx_neteq(ipxdp->ipx_sna, ipxdp->ipx_dna))
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"net of interface (%s) != net on ether (%s)!\n",
|
||||
ipxdp_nettoa(ipxdp->ipx_dna.x_net),
|
||||
ipxdp_nettoa(ipxdp->ipx_sna.x_net));
|
||||
}
|
||||
|
||||
/* We get the IPX header in front of the RIF packet*/
|
||||
cc -= sizeof (struct ipx);
|
||||
#define mask(s) (1<<((s)-1))
|
||||
omask = sigblock(mask(SIGALRM));
|
||||
switch(pkt_type) {
|
||||
case SAP_PKT: sap_input(&from, cc);
|
||||
break;
|
||||
case RIP_PKT: rip_input(&from, cc);
|
||||
break;
|
||||
}
|
||||
sigsetmask(omask);
|
||||
}
|
||||
|
||||
int
|
||||
getsocket(type, proto, sipx)
|
||||
int type, proto;
|
||||
struct sockaddr_ipx *sipx;
|
||||
{
|
||||
int domain = sipx->sipx_family;
|
||||
int retry, s, on = 1;
|
||||
|
||||
retry = 1;
|
||||
while ((s = socket(domain, type, proto)) < 0 && retry) {
|
||||
syslog(LOG_ERR, "socket: %m");
|
||||
sleep(5 * retry);
|
||||
retry <<= 1;
|
||||
}
|
||||
if (retry == 0)
|
||||
return (-1);
|
||||
while (bind(s, (struct sockaddr *)sipx, sizeof (*sipx)) < 0 && retry) {
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
sleep(5 * retry);
|
||||
retry <<= 1;
|
||||
}
|
||||
if (retry == 0)
|
||||
return (-1);
|
||||
if (domain==AF_IPX) {
|
||||
struct ipx ipxdp;
|
||||
if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
|
||||
syslog(LOG_ERR, "setsockopt SEE HEADERS: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP)
|
||||
ipxdp.ipx_pt = IPXPROTO_RI;
|
||||
else if (ntohs(sipx->sipx_addr.x_port) == IPXPORT_SAP)
|
||||
#ifdef IPXPROTO_SAP
|
||||
ipxdp.ipx_pt = IPXPROTO_SAP;
|
||||
#else
|
||||
ipxdp.ipx_pt = IPXPROTO_PXP;
|
||||
#endif
|
||||
else {
|
||||
syslog(LOG_ERR, "port should be either RIP or SAP");
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &ipxdp, sizeof(ipxdp))) {
|
||||
syslog(LOG_ERR, "setsockopt SET HEADER: %m");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
|
||||
syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
|
||||
exit(1);
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork and exit on EMT-- for profiling.
|
||||
*/
|
||||
void
|
||||
fkexit()
|
||||
{
|
||||
if (fork() == 0)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
catchtimer()
|
||||
{
|
||||
dobcast = 1;
|
||||
}
|
||||
|
||||
void
|
||||
getinfo()
|
||||
{
|
||||
FILE *fh;
|
||||
|
||||
fh = fopen("/var/log/ipxrouted.dmp", "a");
|
||||
if(fh == NULL)
|
||||
return;
|
||||
|
||||
dumpriptable(fh);
|
||||
dumpsaptable(fh, sap_head);
|
||||
|
||||
fclose(fh);
|
||||
}
|
||||
|
@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include "defs.h"
|
||||
|
||||
/*
|
||||
* Apply the function "f" to all non-passive
|
||||
* interfaces. If the interface supports the
|
||||
* use of broadcasting use it, otherwise address
|
||||
* the output to the known router.
|
||||
*/
|
||||
void
|
||||
toall(f, except, changesonly)
|
||||
void (*f)(struct sockaddr *, int, struct interface *, int);
|
||||
struct rt_entry *except;
|
||||
int changesonly;
|
||||
{
|
||||
register struct interface *ifp;
|
||||
register struct sockaddr *dst;
|
||||
register int flags;
|
||||
register struct rt_entry *trt;
|
||||
int onlist;
|
||||
extern struct interface *ifnet;
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
if (ifp->int_flags & IFF_PASSIVE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't send it on interfaces in the except list.
|
||||
*/
|
||||
onlist = 0;
|
||||
trt = except;
|
||||
while(trt) {
|
||||
if (ifp == trt->rt_ifp) {
|
||||
onlist = 1;
|
||||
break;
|
||||
}
|
||||
trt = trt->rt_clone;
|
||||
}
|
||||
if (onlist)
|
||||
continue;
|
||||
|
||||
dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
|
||||
ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
|
||||
&ifp->int_addr;
|
||||
flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
|
||||
(*f)(dst, flags, ifp, changesonly);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Output a preformed packet.
|
||||
*/
|
||||
void
|
||||
sndmsg(dst, flags, ifp, changesonly)
|
||||
struct sockaddr *dst;
|
||||
int flags;
|
||||
struct interface *ifp;
|
||||
int changesonly;
|
||||
{
|
||||
|
||||
(*afswitch[dst->sa_family].af_output)
|
||||
(ripsock, flags, dst, sizeof (struct rip));
|
||||
TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
|
||||
}
|
||||
|
||||
/*
|
||||
* Supply dst with the contents of the routing tables.
|
||||
* If this won't fit in one packet, chop it up into several.
|
||||
*
|
||||
* This must be done using the split horizon algorithm.
|
||||
* 1. Don't send routing info to the interface from where it was received.
|
||||
* 2. Don't publish an interface to itself.
|
||||
* 3. If a route is received from more than one interface and the cost is
|
||||
* the same, don't publish it on either interface. I am calling this
|
||||
* clones.
|
||||
*/
|
||||
void
|
||||
supply(dst, flags, ifp, changesonly)
|
||||
struct sockaddr *dst;
|
||||
int flags;
|
||||
struct interface *ifp;
|
||||
int changesonly;
|
||||
{
|
||||
register struct rt_entry *rt;
|
||||
register struct rt_entry *crt; /* Clone route */
|
||||
register struct rthash *rh;
|
||||
register struct netinfo *nn;
|
||||
register struct netinfo *n = msg->rip_nets;
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) dst;
|
||||
af_output_t *output = afswitch[dst->sa_family].af_output;
|
||||
int size, metric, ticks;
|
||||
union ipx_net net;
|
||||
int delay = 0;
|
||||
|
||||
if (sipx->sipx_port == 0)
|
||||
sipx->sipx_port = htons(IPXPORT_RIP);
|
||||
|
||||
msg->rip_cmd = ntohs(RIPCMD_RESPONSE);
|
||||
for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)
|
||||
for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
|
||||
size = (char *)n - (char *)msg;
|
||||
if (size >= ((MAXRIPNETS * sizeof (struct netinfo)) +
|
||||
sizeof (msg->rip_cmd))) {
|
||||
(*output)(ripsock, flags, dst, size);
|
||||
TRACE_OUTPUT(ifp, dst, size);
|
||||
n = msg->rip_nets;
|
||||
delay++;
|
||||
if(delay == 2) {
|
||||
usleep(50000);
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (changesonly && !(rt->rt_state & RTS_CHANGED))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This should do rule one and two of the split horizon
|
||||
* algorithm.
|
||||
*/
|
||||
if (rt->rt_ifp == ifp)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Rule 3.
|
||||
* Look if we have clones (different routes to the same
|
||||
* place with exactly the same cost).
|
||||
*
|
||||
* We should not publish on any of the clone interfaces.
|
||||
*/
|
||||
crt = rt->rt_clone;
|
||||
while (crt) {
|
||||
if (crt->rt_ifp == ifp)
|
||||
goto next;
|
||||
crt = crt->rt_clone;
|
||||
}
|
||||
|
||||
sipx = (struct sockaddr_ipx *)&rt->rt_dst;
|
||||
if ((rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST)
|
||||
sipx = (struct sockaddr_ipx *)&rt->rt_router;
|
||||
if (rt->rt_metric == HOPCNT_INFINITY)
|
||||
metric = HOPCNT_INFINITY;
|
||||
else {
|
||||
metric = rt->rt_metric + 1;
|
||||
/*
|
||||
* We don't advertize routes with more than 15 hops.
|
||||
*/
|
||||
if (metric >= HOPCNT_INFINITY)
|
||||
continue;
|
||||
}
|
||||
/* XXX One day we should cater for slow interfaces also. */
|
||||
ticks = rt->rt_ticks + 1;
|
||||
net = sipx->sipx_addr.x_net;
|
||||
|
||||
/*
|
||||
* Make sure that we don't put out a two net entries
|
||||
* for a pt to pt link (one for the G route, one for the if)
|
||||
* This is a kludge, and won't work if there are lots of nets.
|
||||
*/
|
||||
for (nn = msg->rip_nets; nn < n; nn++) {
|
||||
if (ipx_neteqnn(net, nn->rip_dst)) {
|
||||
if (ticks < ntohs(nn->rip_ticks)) {
|
||||
nn->rip_metric = htons(metric);
|
||||
nn->rip_ticks = htons(ticks);
|
||||
} else if ((ticks == ntohs(nn->rip_ticks)) &&
|
||||
(metric < ntohs(nn->rip_metric))) {
|
||||
nn->rip_metric = htons(metric);
|
||||
nn->rip_ticks = htons(ticks);
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
n->rip_dst = net;
|
||||
n->rip_metric = htons(metric);
|
||||
n->rip_ticks = htons(ticks);
|
||||
n++;
|
||||
next:;
|
||||
}
|
||||
if (n != msg->rip_nets) {
|
||||
size = (char *)n - (char *)msg;
|
||||
(*output)(ripsock, flags, dst, size);
|
||||
TRACE_OUTPUT(ifp, dst, size);
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)protocol.h 8.1 (Berkeley) 6/5/93
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* IPX Routing Information Protocol
|
||||
*
|
||||
*/
|
||||
|
||||
struct netinfo {
|
||||
union ipx_net rip_dst; /* destination net */
|
||||
u_short rip_metric; /* cost of route */
|
||||
u_short rip_ticks; /* cost of route */
|
||||
};
|
||||
|
||||
struct rip {
|
||||
u_short rip_cmd; /* request/response */
|
||||
struct netinfo rip_nets[1]; /* variable length */
|
||||
};
|
||||
|
||||
/*
|
||||
* Packet types.
|
||||
*/
|
||||
#define RIPCMD_REQUEST 1 /* want info */
|
||||
#define RIPCMD_RESPONSE 2 /* responding to request */
|
||||
|
||||
#define RIPCMD_MAX 3
|
||||
#ifdef RIPCMDS
|
||||
char *ripcmds[RIPCMD_MAX] =
|
||||
{ "#0", "REQUEST", "RESPONSE" };
|
||||
#endif
|
||||
|
||||
#define HOPCNT_INFINITY 16 /* per IPX */
|
||||
#define DSTNETS_ALL 0xffffffff /* per IPX */
|
||||
#define MAXRXPACKETSIZE 1500 /* max rx broadcast size */
|
||||
#define MAXRIPNETS 50 /* max nets in tx packet */
|
||||
|
||||
extern union ipx_net ipx_anynet;
|
||||
extern union ipx_net ipx_zeronet;
|
||||
|
||||
/*
|
||||
* Timer values used in managing the routing table.
|
||||
* Every update forces an entry's timer to be reset. After
|
||||
* EXPIRE_TIME without updates, the entry is marked invalid,
|
||||
* but held onto until GARBAGE_TIME so that others may
|
||||
* see it "be deleted".
|
||||
*/
|
||||
#define TIMER_RATE 30 /* alarm clocks every 30 seconds */
|
||||
|
||||
#define SUPPLY_INTERVAL 30 /* time to supply tables */
|
||||
#define RIP_INTERVAL 60 /* time to supply rip tables */
|
||||
|
||||
#define EXPIRE_TIME 180 /* time to mark entry invalid */
|
||||
#define GARBAGE_TIME 240 /* time to garbage collect */
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Hay.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _SAP_H_
|
||||
#define _SAP_H_
|
||||
|
||||
#define SAP_REQ 1
|
||||
#define SAP_RESP 2
|
||||
#define SAP_REQ_NEAR 3
|
||||
#define SAP_RESP_NEAR 4
|
||||
|
||||
#define SAPCMD_MAX 5
|
||||
#ifdef SAPCMDS
|
||||
char *sapcmds[SAPCMD_MAX] =
|
||||
{ "#0", "REQUEST", "RESPONSE", "REQ NEAREST", "RESP NEAREST"};
|
||||
#endif
|
||||
|
||||
#define MAXSAPENTRIES 7
|
||||
#define SAP_WILDCARD 0xFFFF
|
||||
#define SERVNAMELEN 48
|
||||
typedef struct sap_info {
|
||||
u_short ServType;
|
||||
char ServName[SERVNAMELEN];
|
||||
struct ipx_addr ipx;
|
||||
u_short hops;
|
||||
}sap_info;
|
||||
|
||||
typedef struct sap_packet {
|
||||
u_short sap_cmd;
|
||||
sap_info sap[0]; /* Variable length. */
|
||||
}sap_packet;
|
||||
|
||||
typedef struct sap_entry {
|
||||
struct sap_entry *forw;
|
||||
struct sap_entry *back;
|
||||
struct sap_entry *clone;
|
||||
struct interface *ifp;
|
||||
struct sap_info sap;
|
||||
struct sockaddr source;
|
||||
int hash;
|
||||
int state;
|
||||
int timer;
|
||||
}sap_entry;
|
||||
|
||||
#define SAPHASHSIZ 256 /* Should be a power of 2 */
|
||||
#define SAPHASHMASK (SAPHASHSIZ-1)
|
||||
typedef struct sap_hash {
|
||||
struct sap_entry *forw;
|
||||
struct sap_entry *back;
|
||||
}sap_hash;
|
||||
|
||||
extern sap_hash sap_head[SAPHASHSIZ];
|
||||
|
||||
extern struct sap_packet *sap_msg;
|
||||
|
||||
void sapinit(void);
|
||||
void sap_input(struct sockaddr *from, int size);
|
||||
void sapsndmsg(struct sockaddr *dst, int flags, struct interface *ifp,
|
||||
int changesonly);
|
||||
void sap_supply_toall(int changesonly);
|
||||
void sap_supply(struct sockaddr *dst,
|
||||
int flags,
|
||||
struct interface *ifp,
|
||||
int ServType,
|
||||
int changesonly);
|
||||
|
||||
struct sap_entry *sap_lookup(u_short ServType, char *ServName);
|
||||
struct sap_entry *sap_nearestserver(ushort ServType, struct interface *ifp);
|
||||
void sap_add(struct sap_info *si, struct sockaddr *from);
|
||||
void sap_change(struct sap_entry *sap,
|
||||
struct sap_info *si,
|
||||
struct sockaddr *from);
|
||||
void sap_add_clone(struct sap_entry *sap,
|
||||
struct sap_info *clone,
|
||||
struct sockaddr *from);
|
||||
void sap_delete(struct sap_entry *sap);
|
||||
|
||||
#endif /*_SAP_H_*/
|
||||
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Hay.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* IPX Routing Table Management Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
|
||||
int dognreply = 1;
|
||||
|
||||
/*
|
||||
* Process a newly received packet.
|
||||
*/
|
||||
void
|
||||
sap_input(from, size)
|
||||
struct sockaddr *from;
|
||||
int size;
|
||||
{
|
||||
int newsize;
|
||||
int sapchanged = 0;
|
||||
struct sap_entry *sap;
|
||||
struct sap_info *n;
|
||||
struct interface *ifp = 0;
|
||||
struct afswitch *afp;
|
||||
struct sockaddr_ipx *ipxp;
|
||||
|
||||
ifp = if_ifwithnet(from);
|
||||
ipxp = (struct sockaddr_ipx *)from;
|
||||
if (ifp == 0) {
|
||||
if(ftrace) {
|
||||
fprintf(ftrace, "Received bogus packet from %s\n",
|
||||
ipxdp_ntoa(&ipxp->sipx_addr));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftrace)
|
||||
dumpsappacket(ftrace, "received", from, (char *)sap_msg , size);
|
||||
|
||||
if (from->sa_family >= AF_MAX)
|
||||
return;
|
||||
afp = &afswitch[from->sa_family];
|
||||
|
||||
size -= sizeof (u_short) /* command */;
|
||||
n = sap_msg->sap;
|
||||
|
||||
switch (ntohs(sap_msg->sap_cmd)) {
|
||||
|
||||
case SAP_REQ_NEAR:
|
||||
if (ftrace)
|
||||
fprintf(ftrace, "Received a sap REQ_NEAR packet.\n");
|
||||
if (!dognreply)
|
||||
return;
|
||||
sap = sap_nearestserver(n->ServType, ifp);
|
||||
if (sap == NULL)
|
||||
return;
|
||||
sap_msg->sap_cmd = htons(SAP_RESP_NEAR);
|
||||
*n = sap->sap;
|
||||
n->hops = htons(ntohs(n->hops) + 1);
|
||||
if (ntohs(n->hops) >= HOPCNT_INFINITY)
|
||||
return;
|
||||
|
||||
newsize = sizeof(struct sap_info) + sizeof(struct sap_packet);
|
||||
(*afp->af_output)(sapsock, 0, from, newsize);
|
||||
if (ftrace) {
|
||||
fprintf(ftrace, "sap_nearestserver %X %s returned:\n",
|
||||
ntohs(n->ServType),
|
||||
ifp->int_name);
|
||||
fprintf(ftrace, " service %04X %-20.20s "
|
||||
"addr %s.%04X metric %d\n",
|
||||
ntohs(sap->sap.ServType),
|
||||
sap->sap.ServName,
|
||||
ipxdp_ntoa(&sap->sap.ipx),
|
||||
ntohs(sap->sap.ipx.x_port),
|
||||
ntohs(sap->sap.hops));
|
||||
}
|
||||
return;
|
||||
|
||||
case SAP_REQ:
|
||||
if (ftrace)
|
||||
fprintf(ftrace, "Received a sap REQ packet.\n");
|
||||
|
||||
sap_supply(from, 0, ifp, n->ServType, 0);
|
||||
return;
|
||||
|
||||
case SAP_RESP_NEAR:
|
||||
/* XXX We do nothing here, for the moment.
|
||||
* Maybe we should check if the service is in our table?
|
||||
*
|
||||
*/
|
||||
if (ftrace)
|
||||
fprintf(ftrace, "Received a sap RESP_NEAR packet.\n");
|
||||
|
||||
return;
|
||||
|
||||
case SAP_RESP:
|
||||
if (ftrace)
|
||||
fprintf(ftrace, "Received a sap RESP packet.\n");
|
||||
|
||||
(*afp->af_canon)(from);
|
||||
|
||||
for (; size > 0; size -= sizeof (struct sap_info), n++) {
|
||||
if (size < sizeof (struct netinfo))
|
||||
break;
|
||||
/*
|
||||
* The idea here is that if the hop count is more
|
||||
* than INFINITY it is bogus and should be discarded.
|
||||
* If it is equal to INFINITY it is a message to say
|
||||
* that a service went down. If we don't already
|
||||
* have it in our tables discard it. Otherwise
|
||||
* update our table and set the timer to EXPIRE_TIME
|
||||
* so that it is removed next time we go through the
|
||||
* tables.
|
||||
*/
|
||||
if (ntohs(n->hops) > HOPCNT_INFINITY)
|
||||
continue;
|
||||
sap = sap_lookup(n->ServType, n->ServName);
|
||||
if (sap == 0) {
|
||||
if (ntohs(n->hops) == HOPCNT_INFINITY)
|
||||
continue;
|
||||
sap_add(n, from);
|
||||
sapchanged = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* A clone is a different route to the same service
|
||||
* with exactly the same cost (metric).
|
||||
* They must all be recorded because those interfaces
|
||||
* must be handled in the same way as the first route
|
||||
* to that service. ie When using the split horizon
|
||||
* algorithm we must look at these interfaces also.
|
||||
*
|
||||
* Update if from gateway and different,
|
||||
* from anywhere and less hops or
|
||||
* getting stale and equivalent.
|
||||
*/
|
||||
if (((ifp != sap->ifp) ||
|
||||
!equal(&sap->source, from)) &&
|
||||
(n->hops == sap->sap.hops) &&
|
||||
(ntohs(n->hops) != HOPCNT_INFINITY)) {
|
||||
register struct sap_entry *tsap = sap->clone;
|
||||
|
||||
while (tsap) {
|
||||
if ((ifp == tsap->ifp) &&
|
||||
equal(&tsap->source, from)) {
|
||||
tsap->timer = 0;
|
||||
break;
|
||||
}
|
||||
tsap = tsap->clone;
|
||||
}
|
||||
if (tsap == NULL) {
|
||||
sap_add_clone(sap, n, from);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((ifp == sap->ifp) &&
|
||||
equal(&sap->source, from) &&
|
||||
(ntohs(n->hops) == ntohs(sap->sap.hops)))
|
||||
sap->timer = 0;
|
||||
else if (((ifp == sap->ifp) &&
|
||||
equal(&sap->source, from) &&
|
||||
(n->hops != sap->sap.hops)) ||
|
||||
(ntohs(n->hops) < ntohs(sap->sap.hops)) ||
|
||||
(sap->timer > (EXPIRE_TIME*2/3) &&
|
||||
ntohs(sap->sap.hops) == ntohs(n->hops) &&
|
||||
ntohs(n->hops) != HOPCNT_INFINITY)) {
|
||||
sap_change(sap, n, from);
|
||||
sapchanged = 1;
|
||||
}
|
||||
}
|
||||
if (sapchanged) {
|
||||
register struct sap_entry *sap;
|
||||
register struct sap_hash *sh;
|
||||
sap_supply_toall(1);
|
||||
|
||||
for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++)
|
||||
for (sap = sh->forw;
|
||||
sap != (struct sap_entry *)sh;
|
||||
sap = sap->forw)
|
||||
sap->state &= ~RTS_CHANGED;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Hay.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include "defs.h"
|
||||
|
||||
/*
|
||||
* Apply the function "f" to all non-passive
|
||||
* interfaces. If the interface supports the
|
||||
* use of broadcasting use it, otherwise address
|
||||
* the output to the known router.
|
||||
*/
|
||||
void
|
||||
sap_supply_toall(changesonly)
|
||||
int changesonly;
|
||||
{
|
||||
register struct interface *ifp;
|
||||
struct sockaddr dst;
|
||||
register struct sockaddr_ipx *ipx_dst;
|
||||
register int flags;
|
||||
extern struct interface *ifnet;
|
||||
|
||||
ipx_dst = (struct sockaddr_ipx *)&dst;
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->int_next) {
|
||||
if (ifp->int_flags & IFF_PASSIVE)
|
||||
continue;
|
||||
|
||||
dst = ifp->int_flags & IFF_BROADCAST ? ifp->int_broadaddr :
|
||||
ifp->int_flags & IFF_POINTOPOINT ? ifp->int_dstaddr :
|
||||
ifp->int_addr;
|
||||
|
||||
ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP);
|
||||
|
||||
flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
|
||||
sap_supply(&dst, flags, ifp, SAP_WILDCARD, changesonly);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sapsndmsg(dst, flags, ifp, changesonly)
|
||||
struct sockaddr *dst;
|
||||
int flags;
|
||||
struct interface *ifp;
|
||||
int changesonly;
|
||||
{
|
||||
struct sockaddr t_dst;
|
||||
struct sockaddr_ipx *ipx_dst;
|
||||
|
||||
t_dst = *dst;
|
||||
ipx_dst = (struct sockaddr_ipx *)&t_dst;
|
||||
|
||||
if (ipx_dst->sipx_addr.x_port == 0)
|
||||
ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP);
|
||||
|
||||
(*afswitch[dst->sa_family].af_output)
|
||||
(sapsock, flags, &t_dst,
|
||||
sizeof (struct sap_packet) + sizeof(u_short));
|
||||
TRACE_SAP_OUTPUT(ifp, &t_dst,
|
||||
sizeof (struct sap_packet) + sizeof(u_short));
|
||||
}
|
||||
|
||||
/*
|
||||
* Supply dst with the contents of the SAP tables. If the ServType ==
|
||||
* SAP_WILDCARD (0xFFFF) supply the whole table, otherwise only the
|
||||
* services that are of ServType. If this won't fit in one packet, chop
|
||||
* it up into several.
|
||||
*
|
||||
* This must be done using the split horizon algorithm.
|
||||
* 1. Don't send SAP info to the interface from where it was received.
|
||||
* 2. If a service is received from more than one interface and the cost is
|
||||
* the same, don't publish it on either interface. I am calling this
|
||||
* clones.
|
||||
*/
|
||||
void
|
||||
sap_supply(dst, flags, ifp, ServType, changesonly)
|
||||
struct sockaddr *dst;
|
||||
int flags;
|
||||
struct interface *ifp;
|
||||
int ServType;
|
||||
int changesonly;
|
||||
{
|
||||
register struct sap_entry *sap;
|
||||
register struct sap_entry *csap; /* Clone route */
|
||||
register struct sap_hash *sh;
|
||||
register struct sap_info *n = sap_msg->sap;
|
||||
struct sap_hash *base = sap_head;
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) dst;
|
||||
af_output_t *output = afswitch[dst->sa_family].af_output;
|
||||
int size, metric;
|
||||
int delay = 0;
|
||||
|
||||
if (sipx->sipx_port == 0)
|
||||
sipx->sipx_port = htons(IPXPORT_SAP);
|
||||
|
||||
sap_msg->sap_cmd = ntohs(SAP_RESP);
|
||||
|
||||
for (sh = base; sh < &base[SAPHASHSIZ]; sh++)
|
||||
for (sap = sh->forw; sap != (struct sap_entry *)sh; sap = sap->forw) {
|
||||
size = (char *)n - (char *)sap_msg;
|
||||
if (size >= ((MAXSAPENTRIES * sizeof (struct sap_info)) +
|
||||
sizeof (sap_msg->sap_cmd))) {
|
||||
(*output)(sapsock, flags, dst, size);
|
||||
TRACE_SAP_OUTPUT(ifp, dst, size);
|
||||
n = sap_msg->sap;
|
||||
delay++;
|
||||
if(delay == 2) {
|
||||
usleep(50000);
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (changesonly && !(sap->state & RTS_CHANGED))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check for the servicetype except if the ServType is
|
||||
* a wildcard (0xFFFF).
|
||||
*/
|
||||
if ((ServType != SAP_WILDCARD) &&
|
||||
(ServType != sap->sap.ServType))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This should do rule one and two of the split horizon
|
||||
* algorithm.
|
||||
*/
|
||||
if (sap->ifp == ifp)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Rule 2.
|
||||
* Look if we have clones (different routes to the same
|
||||
* place with exactly the same cost).
|
||||
*
|
||||
* We should not publish on any of the clone interfaces.
|
||||
*/
|
||||
csap = sap->clone;
|
||||
while (csap) {
|
||||
if (csap->ifp == ifp)
|
||||
goto next;
|
||||
csap = csap->clone;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't advertise services with more than 15 hops. It
|
||||
* will be confused with a service that has gone down.
|
||||
*/
|
||||
if (ntohs(sap->sap.hops) == (HOPCNT_INFINITY - 1))
|
||||
continue;
|
||||
metric = min(ntohs(sap->sap.hops) + 1, HOPCNT_INFINITY);
|
||||
|
||||
*n = sap->sap;
|
||||
n->hops = htons(metric);
|
||||
n++;
|
||||
next:
|
||||
;
|
||||
}
|
||||
if (n != sap_msg->sap) {
|
||||
size = (char *)n - (char *)sap_msg;
|
||||
(*output)(sapsock, flags, dst, size);
|
||||
TRACE_SAP_OUTPUT(ifp, dst, size);
|
||||
}
|
||||
}
|
||||
|
@ -1,321 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Hay.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include <search.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FIXLEN(s) { if ((s)->sa_len == 0) (s)->sa_len = sizeof (*(s));}
|
||||
|
||||
sap_hash sap_head[SAPHASHSIZ];
|
||||
|
||||
void
|
||||
sapinit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<SAPHASHSIZ; i++)
|
||||
sap_head[i].forw = sap_head[i].back =
|
||||
(struct sap_entry *)&sap_head[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* This hash use the first 14 letters of the ServName and the ServType
|
||||
* to create a 32 bit hash value.
|
||||
*/
|
||||
int
|
||||
saphash(u_short ServType, char *ServName)
|
||||
{
|
||||
int hsh, i;
|
||||
char name[SERVNAMELEN];
|
||||
|
||||
bzero(name, SERVNAMELEN);
|
||||
strncpy(name, ServName, SERVNAMELEN);
|
||||
ServName = name;
|
||||
|
||||
hsh = 0;
|
||||
|
||||
#define SMVAL 33
|
||||
|
||||
hsh = hsh * SMVAL + (ServType & 0xff);
|
||||
hsh = hsh * SMVAL + (ServType >> 8);
|
||||
|
||||
for (i=0;i<14;i++) {
|
||||
hsh = hsh * SMVAL + *ServName++;
|
||||
ServName++;
|
||||
}
|
||||
|
||||
#undef SMVAL
|
||||
|
||||
return hsh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for an exact match on ServType and ServName. It is
|
||||
* mostly used by the function that process SAP RESPONSE packets.
|
||||
*
|
||||
* A hash is created and used to index into the hash table. Then
|
||||
* that list is walk through searching for a match.
|
||||
*
|
||||
* If no match is found NULL is returned.
|
||||
*/
|
||||
struct sap_entry *
|
||||
sap_lookup(u_short ServType, char *ServName)
|
||||
{
|
||||
register struct sap_entry *sap;
|
||||
register struct sap_hash *sh;
|
||||
int hsh;
|
||||
|
||||
hsh = saphash(ServType, ServName);
|
||||
sh = &sap_head[hsh & SAPHASHMASK];
|
||||
|
||||
for(sap = sh->forw; sap != (sap_entry *)sh; sap = sap->forw) {
|
||||
if ((hsh == sap->hash) &&
|
||||
(ServType == sap->sap.ServType) &&
|
||||
(strncmp(ServName, sap->sap.ServName, SERVNAMELEN) == 0)) {
|
||||
return sap;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns the nearest service of the specified type. If no
|
||||
* suitable service is found or if that service is on the interface
|
||||
* where the request came from, NULL is returned.
|
||||
*
|
||||
* When checking interfaces clones must be considered also.
|
||||
*
|
||||
* XXX TODO:
|
||||
* Maybe we can use RIP tables to get the fastest service (ticks).
|
||||
*/
|
||||
struct sap_entry *
|
||||
sap_nearestserver(ushort ServType, struct interface *ifp)
|
||||
{
|
||||
register struct sap_entry *sap;
|
||||
struct sap_hash *sh;
|
||||
register struct sap_entry *best = NULL;
|
||||
register int besthops = HOPCNT_INFINITY;
|
||||
|
||||
sh = sap_head;
|
||||
|
||||
for (; sh < &sap_head[SAPHASHSIZ]; sh++)
|
||||
for(sap = sh->forw; sap != (sap_entry *)sh; sap = sap->forw) {
|
||||
if (ServType != sap->sap.ServType)
|
||||
continue;
|
||||
|
||||
if (ntohs(sap->sap.hops) < besthops) {
|
||||
best = sap;
|
||||
besthops = ntohs(best->sap.hops);
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an entry to the SAP table.
|
||||
*
|
||||
* If the malloc fail, the entry will silently be thrown away.
|
||||
*/
|
||||
void
|
||||
sap_add(struct sap_info *si, struct sockaddr *from)
|
||||
{
|
||||
register struct sap_entry *nsap;
|
||||
register struct sap_hash *sh;
|
||||
|
||||
if (ntohs(si->hops) == HOPCNT_INFINITY)
|
||||
return;
|
||||
|
||||
FIXLEN(from);
|
||||
nsap = malloc(sizeof(struct sap_entry));
|
||||
if (nsap == NULL)
|
||||
return;
|
||||
|
||||
nsap->sap = *si;
|
||||
nsap->source = *from;
|
||||
nsap->clone = NULL;
|
||||
nsap->ifp = if_ifwithnet(from);
|
||||
nsap->state = RTS_CHANGED;
|
||||
nsap->timer = 0;
|
||||
nsap->hash = saphash(si->ServType, si->ServName);
|
||||
|
||||
sh = &sap_head[nsap->hash & SAPHASHMASK];
|
||||
|
||||
insque(nsap, sh);
|
||||
TRACE_SAP_ACTION("ADD", nsap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change an existing SAP entry. If a clone exist for the old one,
|
||||
* check if it is cheaper. If it is change to the clone, otherwise
|
||||
* delete all the clones.
|
||||
*/
|
||||
void
|
||||
sap_change(struct sap_entry *sap,
|
||||
struct sap_info *si,
|
||||
struct sockaddr *from)
|
||||
{
|
||||
struct sap_entry *osap = NULL;
|
||||
|
||||
FIXLEN(from);
|
||||
TRACE_SAP_ACTION("CHANGE FROM", sap);
|
||||
/*
|
||||
* If the hopcount (metric) is HOPCNT_INFINITY (16) it means that
|
||||
* a service has gone down. We should keep it like that for 30
|
||||
* seconds, so that it will get broadcast and then change to a
|
||||
* clone if one exist.
|
||||
*/
|
||||
if (sap->clone && (ntohs(si->hops) != HOPCNT_INFINITY)) {
|
||||
/*
|
||||
* There are three possibilities:
|
||||
* 1. The new path is cheaper than the old one.
|
||||
* Free all the clones.
|
||||
*
|
||||
* 2. The new path is the same cost as the old ones.
|
||||
* If it is on the list of clones remove it
|
||||
* from the clone list and free it.
|
||||
*
|
||||
* 3. The new path is more expensive than the old one.
|
||||
* Use the values of the first clone and take it
|
||||
* out of the list, to be freed at the end.
|
||||
*/
|
||||
osap = sap->clone;
|
||||
if (ntohs(osap->sap.hops) > ntohs(si->hops)) {
|
||||
struct sap_entry *nsap;
|
||||
|
||||
while (osap) {
|
||||
nsap = osap->clone;
|
||||
TRACE_SAP_ACTION("DELETE", osap);
|
||||
free(osap);
|
||||
osap = nsap;
|
||||
}
|
||||
sap->clone = NULL;
|
||||
} else if (ntohs(osap->sap.hops) == ntohs(si->hops)) {
|
||||
struct sap_entry *psap;
|
||||
|
||||
psap = sap;
|
||||
while (osap) {
|
||||
if (equal(&osap->source, from)) {
|
||||
psap->clone = osap->clone;
|
||||
TRACE_SAP_ACTION("DELETE", osap);
|
||||
free(osap);
|
||||
osap = psap->clone;
|
||||
} else {
|
||||
psap = osap;
|
||||
osap = osap->clone;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
from = &osap->source;
|
||||
si = &osap->sap;
|
||||
sap->clone = osap->clone;
|
||||
}
|
||||
}
|
||||
sap->sap = *si;
|
||||
sap->source = *from;
|
||||
sap->ifp = if_ifwithnet(from);
|
||||
sap->state = RTS_CHANGED;
|
||||
if (ntohs(si->hops) == HOPCNT_INFINITY)
|
||||
sap->timer = EXPIRE_TIME;
|
||||
else
|
||||
sap->timer = 0;
|
||||
|
||||
if (osap) {
|
||||
TRACE_SAP_ACTION("DELETE", osap);
|
||||
free(osap);
|
||||
}
|
||||
TRACE_SAP_ACTION("CHANGE TO", sap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a clone to the specified SAP entry. A clone is a different
|
||||
* route to the same service. We must know about them when we use
|
||||
* the split horizon algorithm.
|
||||
*
|
||||
* If the malloc fail, the entry will silently be thrown away.
|
||||
*/
|
||||
void
|
||||
sap_add_clone(struct sap_entry *sap,
|
||||
struct sap_info *clone,
|
||||
struct sockaddr *from)
|
||||
{
|
||||
register struct sap_entry *nsap;
|
||||
register struct sap_entry *csap;
|
||||
|
||||
if (ntohs(clone->hops) == HOPCNT_INFINITY)
|
||||
return;
|
||||
|
||||
FIXLEN(from);
|
||||
nsap = malloc(sizeof(struct sap_entry));
|
||||
if (nsap == NULL)
|
||||
return;
|
||||
|
||||
if (ftrace)
|
||||
fprintf(ftrace, "CLONE ADD %4.4X %s.\n",
|
||||
ntohs(clone->ServType),
|
||||
clone->ServName);
|
||||
|
||||
nsap->sap = *clone;
|
||||
nsap->source = *from;
|
||||
nsap->clone = NULL;
|
||||
nsap->ifp = if_ifwithnet(from);
|
||||
nsap->state = RTS_CHANGED;
|
||||
nsap->timer = 0;
|
||||
nsap->hash = saphash(clone->ServType, clone->ServName);
|
||||
|
||||
csap = sap;
|
||||
while (csap->clone)
|
||||
csap = csap->clone;
|
||||
csap->clone = nsap;
|
||||
TRACE_SAP_ACTION("ADD CLONE", nsap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a SAP entry from the table and free the memory
|
||||
* used by it.
|
||||
*
|
||||
* If the service have clone, do a sap_change to it and free
|
||||
* the clone.
|
||||
*/
|
||||
void
|
||||
sap_delete(struct sap_entry *sap)
|
||||
{
|
||||
if (sap->clone) {
|
||||
sap_change(sap, &sap->clone->sap, &sap->clone->source);
|
||||
return;
|
||||
}
|
||||
remque(sap);
|
||||
TRACE_SAP_ACTION("DELETE", sap);
|
||||
free(sap);
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)startup.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <nlist.h>
|
||||
#include <search.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct interface *ifnet;
|
||||
int lookforinterfaces = 1;
|
||||
int performnlist = 1;
|
||||
int gateway = 0;
|
||||
int externalinterfaces = 0; /* # of remote and local interfaces */
|
||||
|
||||
void
|
||||
quit(s)
|
||||
char *s;
|
||||
{
|
||||
int sverrno = errno;
|
||||
|
||||
(void) fprintf(stderr, "IPXroute: ");
|
||||
if (s)
|
||||
(void) fprintf(stderr, "%s: ", s);
|
||||
(void) fprintf(stderr, "%s\n", strerror(sverrno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
struct rt_addrinfo info;
|
||||
/* XXX Sleazy use of local variables throughout file, warning!!!! */
|
||||
#define netmask info.rti_info[RTAX_NETMASK]
|
||||
#define ifaaddr info.rti_info[RTAX_IFA]
|
||||
#define brdaddr info.rti_info[RTAX_BRD]
|
||||
|
||||
void
|
||||
rt_xaddrs(cp, cplim, rtinfo)
|
||||
register caddr_t cp, cplim;
|
||||
register struct rt_addrinfo *rtinfo;
|
||||
{
|
||||
register struct sockaddr *sa;
|
||||
register int i;
|
||||
|
||||
bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info));
|
||||
for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
|
||||
if ((rtinfo->rti_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
|
||||
cp += SA_SIZE(sa);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
void
|
||||
ifinit(void)
|
||||
{
|
||||
struct interface ifs, *ifp;
|
||||
size_t needed;
|
||||
int mib[6], no_ipxaddr = 0, flags = 0;
|
||||
char *buf, *cplim, *cp;
|
||||
register struct if_msghdr *ifm;
|
||||
register struct ifa_msghdr *ifam;
|
||||
struct sockaddr_dl *sdl = 0;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = AF_IPX;
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
mib[5] = 0;
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
|
||||
quit("route-sysctl-estimate");
|
||||
if ((buf = malloc(needed)) == NULL)
|
||||
quit("malloc");
|
||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
|
||||
lookforinterfaces = 0;
|
||||
cplim = buf + needed;
|
||||
for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) {
|
||||
ifm = (struct if_msghdr *)cp;
|
||||
if (ifm->ifm_type == RTM_IFINFO) {
|
||||
bzero(&ifs, sizeof(ifs));
|
||||
ifs.int_flags = flags = ifm->ifm_flags | IFF_INTERFACE;
|
||||
if ((flags & IFF_UP) == 0 || no_ipxaddr)
|
||||
lookforinterfaces = 1;
|
||||
sdl = (struct sockaddr_dl *) (ifm + 1);
|
||||
sdl->sdl_data[sdl->sdl_nlen] = 0;
|
||||
no_ipxaddr = 1;
|
||||
continue;
|
||||
}
|
||||
if (ifm->ifm_type != RTM_NEWADDR)
|
||||
quit("ifinit: out of sync");
|
||||
if ((flags & IFF_UP) == 0)
|
||||
continue;
|
||||
ifam = (struct ifa_msghdr *)ifm;
|
||||
info.rti_addrs = ifam->ifam_addrs;
|
||||
rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info);
|
||||
if (ifaaddr == 0) {
|
||||
syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data);
|
||||
continue;
|
||||
}
|
||||
ifs.int_addr = *ifaaddr;
|
||||
if (ifs.int_addr.sa_family != AF_IPX)
|
||||
continue;
|
||||
no_ipxaddr = 0;
|
||||
if (ifs.int_flags & IFF_POINTOPOINT) {
|
||||
if (brdaddr == 0) {
|
||||
syslog(LOG_ERR, "%s: (get dstaddr)",
|
||||
sdl->sdl_data);
|
||||
continue;
|
||||
}
|
||||
if (brdaddr->sa_family == AF_UNSPEC) {
|
||||
lookforinterfaces = 1;
|
||||
continue;
|
||||
}
|
||||
ifs.int_dstaddr = *brdaddr;
|
||||
}
|
||||
if (ifs.int_flags & IFF_BROADCAST) {
|
||||
if (brdaddr == 0) {
|
||||
syslog(LOG_ERR, "%s: (get broadaddr)",
|
||||
sdl->sdl_data);
|
||||
continue;
|
||||
}
|
||||
ifs.int_dstaddr = *brdaddr;
|
||||
}
|
||||
if (ifs.int_flags & IFF_LOOPBACK) {
|
||||
ifs.int_dstaddr = ifs.int_addr;
|
||||
}
|
||||
/*
|
||||
* already known to us?
|
||||
* what makes a POINTOPOINT if unique is its dst addr,
|
||||
* NOT its source address
|
||||
*/
|
||||
if ( ((ifs.int_flags & IFF_POINTOPOINT) &&
|
||||
if_ifwithdstaddr(&ifs.int_dstaddr)) ||
|
||||
( ((ifs.int_flags & IFF_POINTOPOINT) == 0) &&
|
||||
if_ifwithaddr(&ifs.int_addr)))
|
||||
continue;
|
||||
ifp = (struct interface *)
|
||||
malloc(sdl->sdl_nlen + 1 + sizeof(ifs));
|
||||
if (ifp == 0) {
|
||||
syslog(LOG_ERR, "IPXrouted: out of memory\n");
|
||||
lookforinterfaces = 1;
|
||||
break;
|
||||
}
|
||||
*ifp = ifs;
|
||||
/*
|
||||
* 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)
|
||||
externalinterfaces++;
|
||||
/*
|
||||
* 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)
|
||||
supplier = 1;
|
||||
ifp->int_name = (char *)(ifp + 1);
|
||||
strcpy(ifp->int_name, sdl->sdl_data);
|
||||
|
||||
ifp->int_metric = ifam->ifam_metric;
|
||||
ifp->int_next = ifnet;
|
||||
ifnet = ifp;
|
||||
traceinit(ifp);
|
||||
addrouteforif(ifp);
|
||||
}
|
||||
if (externalinterfaces > 1 && supplier < 0)
|
||||
supplier = 1;
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void
|
||||
addrouteforif(ifp)
|
||||
struct interface *ifp;
|
||||
{
|
||||
struct sockaddr_ipx net;
|
||||
struct sockaddr *dst;
|
||||
struct rt_entry *rt;
|
||||
|
||||
if (ifp->int_flags & IFF_POINTOPOINT) {
|
||||
int (*match)();
|
||||
register struct interface *ifp2 = ifnet;
|
||||
|
||||
dst = &ifp->int_dstaddr;
|
||||
|
||||
/* 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;
|
||||
if (match)
|
||||
for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) {
|
||||
if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
|
||||
continue;
|
||||
if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) {
|
||||
insque(&ifp2->int_sq,&ifp->int_sq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bzero(&net, sizeof(net));
|
||||
net.sipx_family = AF_IPX;
|
||||
net.sipx_len = sizeof (net);
|
||||
net.sipx_addr.x_net = satoipx_addr(ifp->int_broadaddr).x_net;
|
||||
dst = (struct sockaddr *)&net;
|
||||
}
|
||||
rt = rtlookup(dst);
|
||||
if (rt)
|
||||
rtdelete(rt);
|
||||
if (tracing)
|
||||
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, 0,
|
||||
ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
|
||||
}
|
||||
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)table.h 5.1 (Berkeley) 6/4/85 (routed/table.h)
|
||||
*
|
||||
* @(#)table.h 8.1 (Berkeley) 6/5/93
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routing table management daemon.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routing table structure; differs a bit from kernel tables.
|
||||
*
|
||||
* Note: the union below must agree in the first 4 members
|
||||
* so the ioctl's will work.
|
||||
*/
|
||||
struct rthash {
|
||||
struct rt_entry *rt_forw;
|
||||
struct rt_entry *rt_back;
|
||||
};
|
||||
|
||||
#ifdef RTM_ADD
|
||||
#define rtentry ortentry
|
||||
#endif
|
||||
|
||||
struct rt_entry {
|
||||
struct rt_entry *rt_forw;
|
||||
struct rt_entry *rt_back;
|
||||
union {
|
||||
struct rtentry rtu_rt;
|
||||
struct rtuentry {
|
||||
u_long rtu_hash;
|
||||
struct sockaddr rtu_dst;
|
||||
struct sockaddr rtu_router;
|
||||
short rtu_rtflags; /* used by old rtioctl */
|
||||
short rtu_wasted; /* XXX routed does it this way. */
|
||||
int rtu_flags;
|
||||
int rtu_state;
|
||||
int rtu_timer;
|
||||
int rtu_metric;
|
||||
int rtu_ticks;
|
||||
struct interface *rtu_ifp;
|
||||
} rtu_entry;
|
||||
} rt_rtu;
|
||||
struct rt_entry *rt_clone;
|
||||
};
|
||||
|
||||
#define rt_rt rt_rtu.rtu_entry /* pass to ioctl */
|
||||
#define rt_hash rt_rtu.rtu_entry.rtu_hash /* for net or host */
|
||||
#define rt_dst rt_rtu.rtu_entry.rtu_dst /* match value */
|
||||
#define rt_router rt_rtu.rtu_entry.rtu_router /* who to forward to */
|
||||
#define rt_flags rt_rtu.rtu_entry.rtu_flags /* kernel flags */
|
||||
#define rt_timer rt_rtu.rtu_entry.rtu_timer /* for invalidation */
|
||||
#define rt_state rt_rtu.rtu_entry.rtu_state /* see below */
|
||||
#define rt_metric rt_rtu.rtu_entry.rtu_metric /* cost of route */
|
||||
#define rt_ticks rt_rtu.rtu_entry.rtu_ticks /* time of route */
|
||||
#define rt_ifp rt_rtu.rtu_entry.rtu_ifp /* interface to take */
|
||||
|
||||
#define ROUTEHASHSIZ 128 /* must be a power of 2 */
|
||||
#define ROUTEHASHMASK (ROUTEHASHSIZ - 1)
|
||||
|
||||
/*
|
||||
* "State" of routing table entry.
|
||||
*/
|
||||
#define RTS_CHANGED 0x1 /* route has been altered recently */
|
||||
#define RTS_PASSIVE IFF_PASSIVE /* don't time out route */
|
||||
#define RTS_INTERFACE IFF_INTERFACE /* route is for network interface */
|
||||
#define RTS_REMOTE IFF_REMOTE /* route is for ``remote'' entity */
|
||||
|
||||
extern struct rthash nethash[ROUTEHASHSIZ];
|
||||
struct rt_entry *rtlookup(struct sockaddr *);
|
||||
struct rt_entry *rtfind(struct sockaddr *);
|
||||
void rtadd(struct sockaddr *, struct sockaddr *, short, short, int);
|
||||
void rtadd_clone(struct rt_entry *, struct sockaddr *, struct sockaddr *,
|
||||
short, short, int);
|
||||
void rtchange(struct rt_entry *, struct sockaddr *, short, short);
|
||||
void rtdelete(struct rt_entry *);
|
||||
int rtioctl(int, struct rtuentry *);
|
||||
void rtinit(void);
|
||||
|
@ -1,419 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <search.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
#define FIXLEN(s) { if ((s)->sa_len == 0) (s)->sa_len = sizeof (*(s));}
|
||||
|
||||
int install = !DEBUG; /* if 1 call kernel */
|
||||
int delete = 1;
|
||||
|
||||
struct rthash nethash[ROUTEHASHSIZ];
|
||||
|
||||
/*
|
||||
* Lookup dst in the tables for an exact match.
|
||||
*/
|
||||
struct rt_entry *
|
||||
rtlookup(struct sockaddr *dst)
|
||||
{
|
||||
register struct rt_entry *rt;
|
||||
register struct rthash *rh;
|
||||
register u_int hash;
|
||||
struct afhash h;
|
||||
|
||||
if (dst->sa_family >= AF_MAX)
|
||||
return (0);
|
||||
(*afswitch[dst->sa_family].af_hash)(dst, &h);
|
||||
hash = h.afh_nethash;
|
||||
rh = &nethash[hash & ROUTEHASHMASK];
|
||||
for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
|
||||
if (rt->rt_hash != hash)
|
||||
continue;
|
||||
if (equal(&rt->rt_dst, dst))
|
||||
return (rt);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a route to dst as the kernel would.
|
||||
*/
|
||||
struct rt_entry *
|
||||
rtfind(struct sockaddr *dst)
|
||||
{
|
||||
register struct rt_entry *rt;
|
||||
register struct rthash *rh;
|
||||
register u_int hash;
|
||||
struct afhash h;
|
||||
int af = dst->sa_family;
|
||||
int (*match)() = 0;
|
||||
|
||||
if (af >= AF_MAX)
|
||||
return (0);
|
||||
(*afswitch[af].af_hash)(dst, &h);
|
||||
|
||||
hash = h.afh_nethash;
|
||||
rh = &nethash[hash & ROUTEHASHMASK];
|
||||
match = afswitch[af].af_netmatch;
|
||||
for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
|
||||
if (rt->rt_hash != hash)
|
||||
continue;
|
||||
if (rt->rt_dst.sa_family == af &&
|
||||
(*match)(&rt->rt_dst, dst))
|
||||
return (rt);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
rtadd(struct sockaddr *dst, struct sockaddr *gate, short metric,
|
||||
short ticks, int state)
|
||||
{
|
||||
struct afhash h;
|
||||
register struct rt_entry *rt;
|
||||
struct rthash *rh;
|
||||
int af = dst->sa_family, flags;
|
||||
u_int hash;
|
||||
|
||||
FIXLEN(dst);
|
||||
FIXLEN(gate);
|
||||
if (af >= AF_MAX)
|
||||
return;
|
||||
(*afswitch[af].af_hash)(dst, &h);
|
||||
flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0;
|
||||
hash = h.afh_nethash;
|
||||
rh = &nethash[hash & ROUTEHASHMASK];
|
||||
rt = (struct rt_entry *)malloc(sizeof (*rt));
|
||||
if (rt == 0)
|
||||
return;
|
||||
rt->rt_hash = hash;
|
||||
rt->rt_dst = *dst;
|
||||
rt->rt_router = *gate;
|
||||
rt->rt_metric = metric;
|
||||
rt->rt_ticks = ticks;
|
||||
rt->rt_timer = 0;
|
||||
rt->rt_flags = RTF_UP | flags;
|
||||
rt->rt_state = state | RTS_CHANGED;
|
||||
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
|
||||
rt->rt_clone = NULL;
|
||||
if (metric)
|
||||
rt->rt_flags |= RTF_GATEWAY;
|
||||
insque(rt, rh);
|
||||
TRACE_ACTION("ADD", rt);
|
||||
/*
|
||||
* If the ioctl fails because the gateway is unreachable
|
||||
* from this host, discard the entry. This should only
|
||||
* occur because of an incorrect entry in /etc/gateways.
|
||||
*/
|
||||
if (install && rtioctl(ADD, &rt->rt_rt) < 0) {
|
||||
if (errno != EEXIST)
|
||||
perror("SIOCADDRT");
|
||||
if (errno == ENETUNREACH) {
|
||||
TRACE_ACTION("DELETE", rt);
|
||||
remque(rt);
|
||||
free((char *)rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtadd_clone(struct rt_entry *ort, struct sockaddr *dst,
|
||||
struct sockaddr *gate, short metric, short ticks, int state)
|
||||
{
|
||||
struct afhash h;
|
||||
register struct rt_entry *rt;
|
||||
int af = dst->sa_family, flags;
|
||||
u_int hash;
|
||||
|
||||
FIXLEN(dst);
|
||||
FIXLEN(gate);
|
||||
if (af >= AF_MAX)
|
||||
return;
|
||||
(*afswitch[af].af_hash)(dst, &h);
|
||||
flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0;
|
||||
hash = h.afh_nethash;
|
||||
rt = (struct rt_entry *)malloc(sizeof (*rt));
|
||||
if (rt == 0)
|
||||
return;
|
||||
rt->rt_hash = hash;
|
||||
rt->rt_dst = *dst;
|
||||
rt->rt_router = *gate;
|
||||
rt->rt_metric = metric;
|
||||
rt->rt_ticks = ticks;
|
||||
rt->rt_timer = 0;
|
||||
rt->rt_flags = RTF_UP | flags;
|
||||
rt->rt_state = state | RTS_CHANGED;
|
||||
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
|
||||
rt->rt_clone = NULL;
|
||||
rt->rt_forw = NULL;
|
||||
rt->rt_back = NULL;
|
||||
if (metric)
|
||||
rt->rt_flags |= RTF_GATEWAY;
|
||||
|
||||
while(ort->rt_clone != NULL)
|
||||
ort = ort->rt_clone;
|
||||
ort->rt_clone = rt;
|
||||
TRACE_ACTION("ADD_CLONE", rt);
|
||||
}
|
||||
|
||||
void
|
||||
rtchange(struct rt_entry *rt, struct sockaddr *gate, short metric,
|
||||
short ticks)
|
||||
{
|
||||
int doioctl = 0, metricchanged = 0;
|
||||
|
||||
FIXLEN(gate);
|
||||
/*
|
||||
* Handling of clones.
|
||||
* When the route changed and it had clones, handle it special.
|
||||
* 1. If the new route is cheaper than the clone(s), free the clones.
|
||||
* 2. If the new route is the same cost, it may be one of the clones,
|
||||
* search for it and free it.
|
||||
* 3. If the new route is more expensive than the clone(s), use the
|
||||
* values of the clone(s).
|
||||
*/
|
||||
if (rt->rt_clone) {
|
||||
if ((ticks < rt->rt_clone->rt_ticks) ||
|
||||
((ticks == rt->rt_clone->rt_ticks) &&
|
||||
(metric < rt->rt_clone->rt_metric))) {
|
||||
/*
|
||||
* Free all clones.
|
||||
*/
|
||||
struct rt_entry *trt, *nrt;
|
||||
|
||||
trt = rt->rt_clone;
|
||||
rt->rt_clone = NULL;
|
||||
while(trt) {
|
||||
nrt = trt->rt_clone;
|
||||
free((char *)trt);
|
||||
trt = nrt;
|
||||
}
|
||||
} else if ((ticks == rt->rt_clone->rt_ticks) &&
|
||||
(metric == rt->rt_clone->rt_metric)) {
|
||||
struct rt_entry *prt, *trt;
|
||||
|
||||
prt = rt;
|
||||
trt = rt->rt_clone;
|
||||
|
||||
while(trt) {
|
||||
if (equal(&trt->rt_router, gate)) {
|
||||
prt->rt_clone = trt->rt_clone;
|
||||
free(trt);
|
||||
trt = prt->rt_clone;
|
||||
} else {
|
||||
prt = trt;
|
||||
trt = trt->rt_clone;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Use the values of the first clone.
|
||||
* Delete the corresponding clone.
|
||||
*/
|
||||
struct rt_entry *trt;
|
||||
|
||||
trt = rt->rt_clone;
|
||||
rt->rt_clone = rt->rt_clone->rt_clone;
|
||||
metric = trt->rt_metric;
|
||||
ticks = trt->rt_ticks;
|
||||
*gate = trt->rt_router;
|
||||
free((char *)trt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!equal(&rt->rt_router, gate))
|
||||
doioctl++;
|
||||
if ((metric != rt->rt_metric) || (ticks != rt->rt_ticks))
|
||||
metricchanged++;
|
||||
if (doioctl || metricchanged) {
|
||||
TRACE_ACTION("CHANGE FROM", rt);
|
||||
if (doioctl) {
|
||||
rt->rt_router = *gate;
|
||||
}
|
||||
rt->rt_metric = metric;
|
||||
rt->rt_ticks = ticks;
|
||||
if ((rt->rt_state & RTS_INTERFACE) && metric) {
|
||||
rt->rt_state &= ~RTS_INTERFACE;
|
||||
if(rt->rt_ifp)
|
||||
syslog(LOG_ERR,
|
||||
"changing route from interface %s (timed out)",
|
||||
rt->rt_ifp->int_name);
|
||||
else
|
||||
syslog(LOG_ERR,
|
||||
"changing route from interface ??? (timed out)");
|
||||
}
|
||||
if (metric)
|
||||
rt->rt_flags |= RTF_GATEWAY;
|
||||
else
|
||||
rt->rt_flags &= ~RTF_GATEWAY;
|
||||
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
|
||||
rt->rt_state |= RTS_CHANGED;
|
||||
TRACE_ACTION("CHANGE TO", rt);
|
||||
}
|
||||
if (doioctl && install) {
|
||||
#ifndef RTM_ADD
|
||||
if (rtioctl(ADD, &rt->rt_rt) < 0)
|
||||
syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m",
|
||||
ipx_ntoa(&((struct sockaddr_ipx *)&rt->rt_dst)->sipx_addr),
|
||||
ipx_ntoa(&((struct sockaddr_ipx *)&rt->rt_router)->sipx_addr));
|
||||
if (delete && rtioctl(DELETE, &oldroute) < 0)
|
||||
perror("rtioctl DELETE");
|
||||
#else
|
||||
if (delete == 0) {
|
||||
if (rtioctl(ADD, &rt->rt_rt) >= 0)
|
||||
return;
|
||||
} else {
|
||||
if (rtioctl(CHANGE, &rt->rt_rt) >= 0)
|
||||
return;
|
||||
}
|
||||
syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m",
|
||||
ipxdp_ntoa(&((struct sockaddr_ipx *)&rt->rt_dst)->sipx_addr),
|
||||
ipxdp_ntoa(&((struct sockaddr_ipx *)&rt->rt_router)->sipx_addr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtdelete(struct rt_entry *rt)
|
||||
{
|
||||
|
||||
struct sockaddr *sa = &(rt->rt_router);
|
||||
FIXLEN(sa);
|
||||
sa = &(rt->rt_dst);
|
||||
FIXLEN(sa);
|
||||
if (rt->rt_clone) {
|
||||
/*
|
||||
* If there is a clone we just do a rt_change to it.
|
||||
*/
|
||||
struct rt_entry *trt = rt->rt_clone;
|
||||
rtchange(rt, &trt->rt_router, trt->rt_metric, trt->rt_ticks);
|
||||
return;
|
||||
}
|
||||
if (rt->rt_state & RTS_INTERFACE) {
|
||||
if (rt->rt_ifp)
|
||||
syslog(LOG_ERR,
|
||||
"deleting route to interface %s (timed out)",
|
||||
rt->rt_ifp->int_name);
|
||||
else
|
||||
syslog(LOG_ERR,
|
||||
"deleting route to interface ??? (timed out)");
|
||||
}
|
||||
TRACE_ACTION("DELETE", rt);
|
||||
if (install && rtioctl(DELETE, &rt->rt_rt) < 0)
|
||||
perror("rtioctl DELETE");
|
||||
remque(rt);
|
||||
free((char *)rt);
|
||||
}
|
||||
|
||||
void
|
||||
rtinit(void)
|
||||
{
|
||||
register struct rthash *rh;
|
||||
|
||||
for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)
|
||||
rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
|
||||
}
|
||||
int seqno;
|
||||
|
||||
int
|
||||
rtioctl(int action, struct rtuentry *ort)
|
||||
{
|
||||
#ifndef RTM_ADD
|
||||
if (install == 0)
|
||||
return (errno = 0);
|
||||
|
||||
ort->rtu_rtflags = ort->rtu_flags;
|
||||
|
||||
switch (action) {
|
||||
|
||||
case ADD:
|
||||
return (ioctl(s, SIOCADDRT, (char *)ort));
|
||||
|
||||
case DELETE:
|
||||
return (ioctl(s, SIOCDELRT, (char *)ort));
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
#else /* RTM_ADD */
|
||||
struct {
|
||||
struct rt_msghdr w_rtm;
|
||||
struct sockaddr w_dst;
|
||||
struct sockaddr w_gate;
|
||||
struct sockaddr_ipx w_netmask;
|
||||
} w;
|
||||
#define rtm w.w_rtm
|
||||
|
||||
bzero((char *)&w, sizeof(w));
|
||||
rtm.rtm_msglen = sizeof(w);
|
||||
rtm.rtm_version = RTM_VERSION;
|
||||
rtm.rtm_type = (action == ADD ? RTM_ADD :
|
||||
(action == DELETE ? RTM_DELETE : RTM_CHANGE));
|
||||
rtm.rtm_flags = ort->rtu_flags;
|
||||
rtm.rtm_seq = ++seqno;
|
||||
rtm.rtm_addrs = RTA_DST|RTA_GATEWAY;
|
||||
bcopy((char *)&ort->rtu_dst, (char *)&w.w_dst, sizeof(w.w_dst));
|
||||
bcopy((char *)&ort->rtu_router, (char *)&w.w_gate, sizeof(w.w_gate));
|
||||
w.w_gate.sa_family = w.w_dst.sa_family = AF_IPX;
|
||||
w.w_gate.sa_len = w.w_dst.sa_len = sizeof(w.w_dst);
|
||||
if (rtm.rtm_flags & RTF_HOST) {
|
||||
rtm.rtm_msglen -= sizeof(w.w_netmask);
|
||||
} else {
|
||||
rtm.rtm_addrs |= RTA_NETMASK;
|
||||
w.w_netmask = ipx_netmask;
|
||||
rtm.rtm_msglen -= sizeof(w.w_netmask) - ipx_netmask.sipx_len;
|
||||
}
|
||||
errno = 0;
|
||||
return write(r, (char *)&w, rtm.rtm_msglen);
|
||||
#endif /* RTM_ADD */
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)timer.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#include "defs.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int timeval = -TIMER_RATE;
|
||||
|
||||
/*
|
||||
* Timer routine. Performs routing information supply
|
||||
* duties and manages timers on routing and SAP table entries.
|
||||
*/
|
||||
void
|
||||
timer()
|
||||
{
|
||||
register struct rthash *rh;
|
||||
register struct rt_entry *rt;
|
||||
register struct sap_hash *sh;
|
||||
register struct sap_entry *sap;
|
||||
struct sap_hash *sap_base = sap_head;
|
||||
int timetobroadcast, ripbroadcast, sapbroadcast;
|
||||
|
||||
timeval += TIMER_RATE;
|
||||
if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
|
||||
ifinit();
|
||||
timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
|
||||
ripbroadcast = supplier && timetobroadcast &&
|
||||
(timeval % RIP_INTERVAL) == 0;
|
||||
sapbroadcast = timetobroadcast && dosap && !ripbroadcast;
|
||||
|
||||
for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) {
|
||||
rt = rh->rt_forw;
|
||||
for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
|
||||
if (rt->rt_clone) {
|
||||
struct rt_entry *trt, *prt;
|
||||
/*
|
||||
* If a clone expire free it and mark the
|
||||
* main route RTS_CHANGED.
|
||||
*/
|
||||
prt = rt;
|
||||
trt = rt->rt_clone;
|
||||
while (trt) {
|
||||
trt->rt_timer += TIMER_RATE;
|
||||
if (trt->rt_timer >= EXPIRE_TIME) {
|
||||
prt->rt_clone = trt->rt_clone;
|
||||
free((char *)trt);
|
||||
trt = prt->rt_clone;
|
||||
rt->rt_state |= RTS_CHANGED;
|
||||
} else {
|
||||
prt = trt;
|
||||
trt = prt->rt_clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We don't advance time on a routing entry for
|
||||
* a passive gateway or that for our only interface.
|
||||
* The latter is excused because we don't act as
|
||||
* a routing information supplier and hence would
|
||||
* time it out. This is fair as if it's down
|
||||
* we're cut off from the world anyway and it's
|
||||
* not likely we'll grow any new hardware in
|
||||
* the mean time.
|
||||
*/
|
||||
if (!(rt->rt_state & RTS_PASSIVE) &&
|
||||
!(rt->rt_state & RTS_INTERFACE))
|
||||
rt->rt_timer += TIMER_RATE;
|
||||
if (rt->rt_timer >= EXPIRE_TIME) {
|
||||
rt->rt_metric = HOPCNT_INFINITY;
|
||||
rt->rt_state |= RTS_CHANGED;
|
||||
}
|
||||
if (rt->rt_timer >= GARBAGE_TIME) {
|
||||
rt = rt->rt_back;
|
||||
/* Perhaps we should send a REQUEST for this route? */
|
||||
rtdelete(rt->rt_forw);
|
||||
continue;
|
||||
}
|
||||
if (rt->rt_state & RTS_CHANGED) {
|
||||
rt->rt_state &= ~RTS_CHANGED;
|
||||
/* don't send extraneous packets */
|
||||
if (!supplier || ripbroadcast)
|
||||
continue;
|
||||
if ((rt->rt_metric + 1) == HOPCNT_INFINITY)
|
||||
continue;
|
||||
msg->rip_cmd = htons(RIPCMD_RESPONSE);
|
||||
msg->rip_nets[0].rip_dst =
|
||||
(satoipx_addr(rt->rt_dst)).x_net;
|
||||
msg->rip_nets[0].rip_metric =
|
||||
htons(min(rt->rt_metric+1, HOPCNT_INFINITY));
|
||||
msg->rip_nets[0].rip_ticks =
|
||||
htons(rt->rt_ticks + 1);
|
||||
toall(sndmsg, rt, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ripbroadcast)
|
||||
toall(supply, NULL, 0);
|
||||
|
||||
/*
|
||||
* Now do the SAP stuff.
|
||||
*/
|
||||
for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) {
|
||||
sap = sh->forw;
|
||||
for (; sap != (struct sap_entry *)sh; sap = sap->forw) {
|
||||
if (sap->clone) {
|
||||
struct sap_entry *tsap, *psap;
|
||||
/*
|
||||
* If a clone expire free it and mark the
|
||||
* main sap entry RTS_CHANGED.
|
||||
*/
|
||||
psap = sap;
|
||||
tsap = sap->clone;
|
||||
while (tsap) {
|
||||
tsap->timer += TIMER_RATE;
|
||||
if (tsap->timer >= EXPIRE_TIME) {
|
||||
psap->clone = tsap->clone;
|
||||
free((char *)tsap);
|
||||
tsap = psap->clone;
|
||||
sap->state |= RTS_CHANGED;
|
||||
} else {
|
||||
psap = tsap;
|
||||
tsap = psap->clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
sap->timer += TIMER_RATE;
|
||||
if (sap->timer >= EXPIRE_TIME) {
|
||||
sap->sap.hops = htons(HOPCNT_INFINITY);
|
||||
sap->state |= RTS_CHANGED;
|
||||
}
|
||||
if (sap->timer >= GARBAGE_TIME) {
|
||||
sap = sap->back;
|
||||
/* Perhaps we should send a REQUEST for this route? */
|
||||
sap_delete(sap->forw);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* XXX sap_sndmsg on RTS_CHANGED
|
||||
*/
|
||||
if (sap->state & RTS_CHANGED) {
|
||||
sap->state &= ~RTS_CHANGED;
|
||||
#ifdef notyet
|
||||
/* don't send extraneous packets */
|
||||
if (!supplier || sapbroadcast)
|
||||
continue;
|
||||
if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY)
|
||||
continue;
|
||||
sap_msg->sap_cmd = htons(SAP_RESP);
|
||||
sap_msg->sap[0] = sap->sap;
|
||||
sap_msg->sap[0].hops =
|
||||
htons(min(sap->sap.hops+1, HOPCNT_INFINITY));
|
||||
toall(sapsndmsg, rt, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sapbroadcast)
|
||||
sap_supply_toall(0);
|
||||
if (ftrace && sapbroadcast)
|
||||
dumpsaptable(ftrace, sap_head);
|
||||
}
|
||||
|
||||
/*
|
||||
* On hangup, let everyone know we're going away.
|
||||
*/
|
||||
void
|
||||
hup()
|
||||
{
|
||||
register struct rthash *rh;
|
||||
register struct rt_entry *rt;
|
||||
register struct sap_hash *sh;
|
||||
register struct sap_entry *sap;
|
||||
|
||||
if (supplier) {
|
||||
for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) {
|
||||
rt = rh->rt_forw;
|
||||
for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
|
||||
rt->rt_metric = HOPCNT_INFINITY;
|
||||
}
|
||||
toall(supply, NULL, 0);
|
||||
|
||||
/*
|
||||
* Now for SAP.
|
||||
*/
|
||||
for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) {
|
||||
sap = sh->forw;
|
||||
for (; sap != (struct sap_entry *)sh; sap = sap->forw)
|
||||
sap->sap.hops = htons(HOPCNT_INFINITY);
|
||||
}
|
||||
if (dosap)
|
||||
sap_supply_toall(0);
|
||||
}
|
||||
exit(1);
|
||||
}
|
@ -1,520 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Routing Table Management Daemon
|
||||
*/
|
||||
#define RIPCMDS
|
||||
#define SAPCMDS
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "defs.h"
|
||||
|
||||
#define NRECORDS 50 /* size of circular trace buffer */
|
||||
#ifdef DEBUG
|
||||
FILE *ftrace = stdout;
|
||||
int tracing = 1;
|
||||
#else /* DEBUG */
|
||||
FILE *ftrace = NULL;
|
||||
int tracing = 0;
|
||||
#endif
|
||||
|
||||
void dumpif(FILE *fd, struct interface *ifp);
|
||||
void dumptrace(FILE *fd, char *dir, struct ifdebug *ifd);
|
||||
static int iftraceinit(struct interface *ifp, struct ifdebug *ifd);
|
||||
|
||||
void
|
||||
traceinit(ifp)
|
||||
register struct interface *ifp;
|
||||
{
|
||||
if (iftraceinit(ifp, &ifp->int_input) &&
|
||||
iftraceinit(ifp, &ifp->int_output))
|
||||
return;
|
||||
tracing = 0;
|
||||
syslog(LOG_ERR, "traceinit: can't init %s\n", ifp->int_name);
|
||||
}
|
||||
|
||||
static int
|
||||
iftraceinit(ifp, ifd)
|
||||
struct interface *ifp;
|
||||
register struct ifdebug *ifd;
|
||||
{
|
||||
register struct iftrace *t;
|
||||
|
||||
ifd->ifd_records =
|
||||
(struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
|
||||
if (ifd->ifd_records == 0)
|
||||
return (0);
|
||||
ifd->ifd_front = ifd->ifd_records;
|
||||
ifd->ifd_count = 0;
|
||||
for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
|
||||
t->ift_size = 0;
|
||||
t->ift_packet = 0;
|
||||
}
|
||||
ifd->ifd_if = ifp;
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
traceon(file)
|
||||
char *file;
|
||||
{
|
||||
|
||||
if (ftrace != NULL)
|
||||
return;
|
||||
ftrace = fopen(file, "a");
|
||||
if (ftrace == NULL)
|
||||
return;
|
||||
dup2(fileno(ftrace), 1);
|
||||
dup2(fileno(ftrace), 2);
|
||||
tracing = 1;
|
||||
}
|
||||
|
||||
void
|
||||
traceoff(void)
|
||||
{
|
||||
if (!tracing)
|
||||
return;
|
||||
if (ftrace != NULL)
|
||||
fclose(ftrace);
|
||||
ftrace = NULL;
|
||||
tracing = 0;
|
||||
}
|
||||
|
||||
void
|
||||
trace(ifd, who, p, len, m)
|
||||
register struct ifdebug *ifd;
|
||||
struct sockaddr *who;
|
||||
char *p;
|
||||
int len, m;
|
||||
{
|
||||
register struct iftrace *t;
|
||||
|
||||
if (ifd->ifd_records == 0)
|
||||
return;
|
||||
t = ifd->ifd_front++;
|
||||
if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
|
||||
ifd->ifd_front = ifd->ifd_records;
|
||||
if (ifd->ifd_count < NRECORDS)
|
||||
ifd->ifd_count++;
|
||||
if (t->ift_size > 0 && t->ift_packet)
|
||||
free(t->ift_packet);
|
||||
t->ift_packet = 0;
|
||||
t->ift_stamp = time(0);
|
||||
t->ift_who = *who;
|
||||
if (len > 0) {
|
||||
t->ift_packet = malloc(len);
|
||||
if (t->ift_packet)
|
||||
bcopy(p, t->ift_packet, len);
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
t->ift_size = len;
|
||||
t->ift_metric = m;
|
||||
}
|
||||
|
||||
void
|
||||
traceaction(fd, action, rt)
|
||||
FILE *fd;
|
||||
char *action;
|
||||
struct rt_entry *rt;
|
||||
{
|
||||
struct sockaddr_ipx *dst, *gate;
|
||||
static struct bits {
|
||||
int t_bits;
|
||||
char *t_name;
|
||||
} flagbits[] = {
|
||||
{ RTF_UP, "UP" },
|
||||
{ RTF_GATEWAY, "GATEWAY" },
|
||||
{ RTF_HOST, "HOST" },
|
||||
{ 0 }
|
||||
}, statebits[] = {
|
||||
{ RTS_PASSIVE, "PASSIVE" },
|
||||
{ RTS_REMOTE, "REMOTE" },
|
||||
{ RTS_INTERFACE,"INTERFACE" },
|
||||
{ RTS_CHANGED, "CHANGED" },
|
||||
{ 0 }
|
||||
};
|
||||
register struct bits *p;
|
||||
register int first;
|
||||
char *cp;
|
||||
|
||||
if (fd == NULL)
|
||||
return;
|
||||
fprintf(fd, "%s ", action);
|
||||
dst = (struct sockaddr_ipx *)&rt->rt_dst;
|
||||
gate = (struct sockaddr_ipx *)&rt->rt_router;
|
||||
fprintf(fd, "dst %s, ", ipxdp_ntoa(&dst->sipx_addr));
|
||||
fprintf(fd, "router %s, metric %d, ticks %d, flags",
|
||||
ipxdp_ntoa(&gate->sipx_addr), rt->rt_metric, rt->rt_ticks);
|
||||
cp = " %s";
|
||||
for (first = 1, p = flagbits; p->t_bits > 0; p++) {
|
||||
if ((rt->rt_flags & p->t_bits) == 0)
|
||||
continue;
|
||||
fprintf(fd, cp, p->t_name);
|
||||
if (first) {
|
||||
cp = "|%s";
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
fprintf(fd, " state");
|
||||
cp = " %s";
|
||||
for (first = 1, p = statebits; p->t_bits > 0; p++) {
|
||||
if ((rt->rt_state & p->t_bits) == 0)
|
||||
continue;
|
||||
fprintf(fd, cp, p->t_name);
|
||||
if (first) {
|
||||
cp = "|%s";
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
putc('\n', fd);
|
||||
if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
|
||||
dumpif(fd, rt->rt_ifp);
|
||||
fflush(fd);
|
||||
}
|
||||
|
||||
void
|
||||
traceactionlog(action, rt)
|
||||
char *action;
|
||||
struct rt_entry *rt;
|
||||
{
|
||||
struct sockaddr_ipx *dst, *gate;
|
||||
static struct bits {
|
||||
int t_bits;
|
||||
char *t_name;
|
||||
} flagbits[] = {
|
||||
{ RTF_UP, "UP" },
|
||||
{ RTF_GATEWAY, "GATEWAY" },
|
||||
{ RTF_HOST, "HOST" },
|
||||
{ 0 }
|
||||
}, statebits[] = {
|
||||
{ RTS_PASSIVE, "PASSIVE" },
|
||||
{ RTS_REMOTE, "REMOTE" },
|
||||
{ RTS_INTERFACE,"INTERFACE" },
|
||||
{ RTS_CHANGED, "CHANGED" },
|
||||
{ 0 }
|
||||
};
|
||||
register struct bits *p;
|
||||
register int first;
|
||||
char *cp;
|
||||
char *lstr, *olstr;
|
||||
|
||||
dst = (struct sockaddr_ipx *)&rt->rt_dst;
|
||||
gate = (struct sockaddr_ipx *)&rt->rt_router;
|
||||
asprintf(&lstr, "%s dst %s,", action, ipxdp_ntoa(&dst->sipx_addr));
|
||||
olstr = lstr;
|
||||
asprintf(&lstr, "%s router %s, metric %d, ticks %d, flags",
|
||||
olstr, ipxdp_ntoa(&gate->sipx_addr), rt->rt_metric, rt->rt_ticks);
|
||||
free(olstr);
|
||||
olstr = lstr;
|
||||
cp = "%s %s";
|
||||
for (first = 1, p = flagbits; p->t_bits > 0; p++) {
|
||||
if ((rt->rt_flags & p->t_bits) == 0)
|
||||
continue;
|
||||
asprintf(&lstr, cp, olstr, p->t_name);
|
||||
free(olstr);
|
||||
olstr = lstr;
|
||||
if (first) {
|
||||
cp = "%s|%s";
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
asprintf(&lstr, "%s state", olstr);
|
||||
free(olstr);
|
||||
olstr = lstr;
|
||||
cp = "%s %s";
|
||||
for (first = 1, p = statebits; p->t_bits > 0; p++) {
|
||||
if ((rt->rt_state & p->t_bits) == 0)
|
||||
continue;
|
||||
asprintf(&lstr, cp, olstr, p->t_name);
|
||||
free(olstr);
|
||||
olstr = lstr;
|
||||
if (first) {
|
||||
cp = "%s|%s";
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
syslog(LOG_DEBUG, "%s", lstr);
|
||||
free(lstr);
|
||||
}
|
||||
|
||||
void
|
||||
tracesapactionlog(action, sap)
|
||||
char *action;
|
||||
struct sap_entry *sap;
|
||||
{
|
||||
syslog(LOG_DEBUG, "%-12.12s service %04X %-20.20s "
|
||||
"addr %s.%04X %c metric %d\n",
|
||||
action,
|
||||
ntohs(sap->sap.ServType),
|
||||
sap->sap.ServName,
|
||||
ipxdp_ntoa(&sap->sap.ipx),
|
||||
ntohs(sap->sap.ipx.x_port),
|
||||
(sap->clone ? 'C' : ' '),
|
||||
ntohs(sap->sap.hops));
|
||||
}
|
||||
|
||||
void
|
||||
dumpif(fd, ifp)
|
||||
register struct interface *ifp;
|
||||
FILE *fd;
|
||||
{
|
||||
if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
|
||||
fprintf(fd, "*** Packet history for interface %s ***\n",
|
||||
ifp->int_name);
|
||||
dumptrace(fd, "to", &ifp->int_output);
|
||||
dumptrace(fd, "from", &ifp->int_input);
|
||||
fprintf(fd, "*** end packet history ***\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dumptrace(fd, dir, ifd)
|
||||
FILE *fd;
|
||||
char *dir;
|
||||
register struct ifdebug *ifd;
|
||||
{
|
||||
register struct iftrace *t;
|
||||
char *cp = !strcmp(dir, "to") ? "Output" : "Input";
|
||||
|
||||
if (ifd->ifd_front == ifd->ifd_records &&
|
||||
ifd->ifd_front->ift_size == 0) {
|
||||
fprintf(fd, "%s: no packets.\n", cp);
|
||||
return;
|
||||
}
|
||||
fprintf(fd, "%s trace:\n", cp);
|
||||
t = ifd->ifd_front - ifd->ifd_count;
|
||||
if (t < ifd->ifd_records)
|
||||
t += NRECORDS;
|
||||
for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
|
||||
if (t >= ifd->ifd_records + NRECORDS)
|
||||
t = ifd->ifd_records;
|
||||
if (t->ift_size == 0)
|
||||
continue;
|
||||
fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
|
||||
t->ift_metric);
|
||||
dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dumppacket(fd, dir, source, cp, size)
|
||||
FILE *fd;
|
||||
char *dir;
|
||||
struct sockaddr *source;
|
||||
char *cp;
|
||||
register int size;
|
||||
{
|
||||
register struct rip *msg = (struct rip *)cp;
|
||||
register struct netinfo *n;
|
||||
struct sockaddr_ipx *who = (struct sockaddr_ipx *)source;
|
||||
|
||||
if (msg->rip_cmd && ntohs(msg->rip_cmd) < RIPCMD_MAX)
|
||||
fprintf(fd, "%s %s %s#%x", ripcmds[ntohs(msg->rip_cmd)],
|
||||
dir, ipxdp_ntoa(&who->sipx_addr),
|
||||
ntohs(who->sipx_addr.x_port));
|
||||
else {
|
||||
fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->rip_cmd),
|
||||
dir, ipxdp_ntoa(&who->sipx_addr),
|
||||
ntohs(who->sipx_addr.x_port));
|
||||
fprintf(fd, "size=%d cp=%p packet=%p\n", size,
|
||||
cp, packet);
|
||||
return;
|
||||
}
|
||||
switch (ntohs(msg->rip_cmd)) {
|
||||
|
||||
case RIPCMD_REQUEST:
|
||||
case RIPCMD_RESPONSE:
|
||||
fprintf(fd, ":\n");
|
||||
size -= sizeof (u_short);
|
||||
n = msg->rip_nets;
|
||||
for (; size > 0; n++, size -= sizeof (struct netinfo)) {
|
||||
if (size < sizeof (struct netinfo))
|
||||
break;
|
||||
fprintf(fd, "\tnet %s metric %d ticks %d\n",
|
||||
ipxdp_nettoa(n->rip_dst),
|
||||
ntohs(n->rip_metric),
|
||||
ntohs(n->rip_ticks));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dumpsappacket(fd, dir, source, cp, size)
|
||||
FILE *fd;
|
||||
char *dir;
|
||||
struct sockaddr *source;
|
||||
char *cp;
|
||||
register int size;
|
||||
{
|
||||
register struct sap_packet *msg = (struct sap_packet *)cp;
|
||||
register struct sap_info *n;
|
||||
struct sockaddr_ipx *who = (struct sockaddr_ipx *)source;
|
||||
|
||||
if (msg->sap_cmd && ntohs(msg->sap_cmd) < SAPCMD_MAX)
|
||||
fprintf(fd, "%s %s %s#%x", sapcmds[ntohs(msg->sap_cmd)],
|
||||
dir, ipxdp_ntoa(&who->sipx_addr),
|
||||
ntohs(who->sipx_addr.x_port));
|
||||
else {
|
||||
fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->sap_cmd),
|
||||
dir, ipxdp_ntoa(&who->sipx_addr),
|
||||
ntohs(who->sipx_addr.x_port));
|
||||
fprintf(fd, "size=%d cp=%p packet=%p\n", size,
|
||||
cp, packet);
|
||||
return;
|
||||
}
|
||||
switch (ntohs(msg->sap_cmd)) {
|
||||
|
||||
case SAP_REQ:
|
||||
case SAP_RESP:
|
||||
case SAP_REQ_NEAR:
|
||||
case SAP_RESP_NEAR:
|
||||
fprintf(fd, ":\n");
|
||||
size -= sizeof (u_short);
|
||||
n = msg->sap;
|
||||
for (; size > 0; n++, size -= sizeof (struct sap_info)) {
|
||||
if (size < sizeof (struct sap_info))
|
||||
break;
|
||||
fprintf(fd, " service %04X %-20.20s "
|
||||
"addr %s.%04X metric %d\n",
|
||||
ntohs(n->ServType),
|
||||
n->ServName,
|
||||
ipxdp_ntoa(&n->ipx),
|
||||
ntohs(n->ipx.x_port),
|
||||
ntohs(n->hops));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dumpsaptable(fd, sh)
|
||||
FILE *fd;
|
||||
struct sap_hash *sh;
|
||||
{
|
||||
register struct sap_entry *sap;
|
||||
struct sap_hash *hash;
|
||||
int x = 0;
|
||||
|
||||
fprintf(fd, "------- SAP table dump. -------\n");
|
||||
for (hash = sh; hash < &sh[SAPHASHSIZ]; hash++, x++) {
|
||||
fprintf(fd, "HASH %d\n", x);
|
||||
sap = hash->forw;
|
||||
for (; sap != (struct sap_entry *)hash; sap = sap->forw) {
|
||||
fprintf(fd, " service %04X %-20.20s "
|
||||
"addr %s.%04X %c metric %d\n",
|
||||
ntohs(sap->sap.ServType),
|
||||
sap->sap.ServName,
|
||||
ipxdp_ntoa(&sap->sap.ipx),
|
||||
ntohs(sap->sap.ipx.x_port),
|
||||
(sap->clone ? 'C' : ' '),
|
||||
ntohs(sap->sap.hops));
|
||||
}
|
||||
}
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dumpriptable(fd)
|
||||
FILE *fd;
|
||||
{
|
||||
register struct rt_entry *rip;
|
||||
struct rthash *hash;
|
||||
int x;
|
||||
struct rthash *rh = nethash;
|
||||
|
||||
fprintf(fd, "------- RIP table dump. -------\n");
|
||||
x = 0;
|
||||
fprintf(fd, "Network table.\n");
|
||||
|
||||
for (hash = rh; hash < &rh[ROUTEHASHSIZ]; hash++, x++) {
|
||||
fprintf(fd, "HASH %d\n", x);
|
||||
rip = hash->rt_forw;
|
||||
for (; rip != (struct rt_entry *)hash; rip = rip->rt_forw) {
|
||||
fprintf(fd, " dest %s\t",
|
||||
ipxdp_ntoa(&satoipx_addr(rip->rt_dst)));
|
||||
fprintf(fd, "%s metric %d, ticks %d\n",
|
||||
ipxdp_ntoa(&satoipx_addr(rip->rt_router)),
|
||||
rip->rt_metric,
|
||||
rip->rt_ticks);
|
||||
}
|
||||
}
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
|
||||
union ipx_net_u net;
|
||||
|
||||
char *
|
||||
ipxdp_nettoa(val)
|
||||
union ipx_net val;
|
||||
{
|
||||
static char buf[100];
|
||||
net.net_e = val;
|
||||
(void)sprintf(buf, "%u", ntohl(net.long_e));
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ipxdp_ntoa(addr)
|
||||
struct ipx_addr *addr;
|
||||
{
|
||||
static char buf[100];
|
||||
|
||||
(void)sprintf(buf, "%s#%x:%x:%x:%x:%x:%x",
|
||||
ipxdp_nettoa(addr->x_net),
|
||||
addr->x_host.c_host[0], addr->x_host.c_host[1],
|
||||
addr->x_host.c_host[2], addr->x_host.c_host[3],
|
||||
addr->x_host.c_host[4], addr->x_host.c_host[5]);
|
||||
|
||||
return(buf);
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1995 John Hay. All rights reserved.
|
||||
*
|
||||
* 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, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)trace.h 8.1 (Berkeley) 6/5/93
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* IPX Routing Information Protocol.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Trace record format.
|
||||
*/
|
||||
struct iftrace {
|
||||
time_t ift_stamp; /* time stamp */
|
||||
struct sockaddr ift_who; /* from/to */
|
||||
char *ift_packet; /* pointer to packet */
|
||||
short ift_size; /* size of packet */
|
||||
short ift_metric; /* metric */
|
||||
};
|
||||
|
||||
/*
|
||||
* Per interface packet tracing buffers. An incoming and
|
||||
* outgoing circular buffer of packets is maintained, per
|
||||
* interface, for debugging. Buffers are dumped whenever
|
||||
* an interface is marked down.
|
||||
*/
|
||||
struct ifdebug {
|
||||
struct iftrace *ifd_records; /* array of trace records */
|
||||
struct iftrace *ifd_front; /* next empty trace record */
|
||||
int ifd_count; /* number of unprinted records */
|
||||
struct interface *ifd_if; /* for locating stuff */
|
||||
};
|
||||
|
||||
/*
|
||||
* Packet tracing stuff.
|
||||
*/
|
||||
int tracepackets; /* watch packets as they go by */
|
||||
int tracing; /* on/off */
|
||||
FILE *ftrace; /* output trace file */
|
||||
|
||||
#define TRACE_ACTION(action, route) { \
|
||||
if (tracing) \
|
||||
traceaction(ftrace, "action", route); \
|
||||
traceactionlog(action, route); \
|
||||
}
|
||||
#define TRACE_SAP_ACTION(action, service) { \
|
||||
tracesapactionlog(action, service); \
|
||||
}
|
||||
#define TRACE_INPUT(ifp, src, size) { \
|
||||
if (tracing) { \
|
||||
ifp = if_iflookup(src); \
|
||||
if (ifp) \
|
||||
trace(&ifp->int_input, src, \
|
||||
&packet[sizeof(struct ipx)], size, \
|
||||
ntohl(ifp->int_metric)); \
|
||||
} \
|
||||
if (tracepackets && ftrace) \
|
||||
dumppacket(ftrace, "from", src, \
|
||||
&packet[sizeof(struct ipx)], size); \
|
||||
}
|
||||
#define TRACE_OUTPUT(ifp, dst, size) { \
|
||||
if (tracing) { \
|
||||
ifp = if_iflookup(dst); \
|
||||
if (ifp) \
|
||||
trace(&ifp->int_output, dst, \
|
||||
&packet[sizeof(struct ipx)], \
|
||||
size, ifp->int_metric); \
|
||||
} \
|
||||
if (tracepackets && ftrace) \
|
||||
dumppacket(ftrace, "to", dst, \
|
||||
&packet[sizeof(struct ipx)], size); \
|
||||
}
|
||||
|
||||
#define TRACE_SAP_OUTPUT(ifp, dst, size) { \
|
||||
if (tracing) { \
|
||||
ifp = if_iflookup(dst); \
|
||||
if (ifp) \
|
||||
trace(&ifp->int_output, dst, \
|
||||
&packet[sizeof(struct ipx)], \
|
||||
size, ifp->int_metric); \
|
||||
} \
|
||||
if (tracepackets && ftrace) \
|
||||
dumpsappacket(ftrace, "to", dst, \
|
||||
&packet[sizeof(struct ipx)], size); \
|
||||
}
|
||||
|
||||
void traceinit(struct interface *);
|
||||
void traceon(char *file);
|
||||
void traceoff(void);
|
||||
void traceaction(FILE *, char *, struct rt_entry *);
|
||||
void traceactionlog(char *, struct rt_entry *);
|
||||
void tracesapactionlog(char *action, struct sap_entry *sap);
|
||||
void trace(struct ifdebug *, struct sockaddr *, char *, int, int);
|
||||
void dumppacket(FILE *, char *, struct sockaddr *, char *, int);
|
||||
void dumpsappacket(FILE *, char *, struct sockaddr *, char *, int);
|
||||
void dumpsaptable(FILE *fd, struct sap_hash *sh);
|
||||
void dumpriptable(FILE *fd);
|
||||
|
||||
char *ipxdp_nettoa(union ipx_net);
|
||||
char *ipxdp_ntoa(struct ipx_addr *);
|
||||
|
Loading…
Reference in New Issue
Block a user