home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume40
/
ipp
/
part04
< prev
next >
Wrap
Text File
|
1993-11-24
|
67KB
|
2,021 lines
Newsgroups: comp.sources.misc
From: db15@ukc.ac.uk (Damiano Bolla)
Subject: v40i162: ipp - IPP Routing Architecture Toolkit, Part04/06
Message-ID: <1993Nov24.193828.7704@sparky.sterling.com>
X-Md4-Signature: e42d34231a50290a9467ee2b26e79fd8
Sender: kent@sparky.sterling.com (Kent Landfield)
Organization: Computing Lab, University of Kent at Canterbury, UK.
Date: Wed, 24 Nov 1993 19:38:28 GMT
Approved: kent@sparky.sterling.com
Submitted-by: db15@ukc.ac.uk (Damiano Bolla)
Posting-number: Volume 40, Issue 162
Archive-name: ipp/part04
Environment: INET
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: IPP/config/ex1/16config IPP/config/ex1/config
# IPP/config/ex2/2config IPP/config/ex2/3config
# IPP/config/ex2/5config IPP/ethernet/Tnet.c IPP/host/HostInit.c
# IPP/include/packet.h IPP/lib/route/FindParentRoute.c
# IPP/lib/route/FindSubnetRoute.c IPP/lib/route/RouteMgr.c
# IPP/lib/utils/Connect.c IPP/lib/utils/Debug.c
# IPP/monitor/monitor.c IPP/router/ParseData.c
# IPP/router/ParsePack.c IPP/router/ProcessPack.c
# IPP/router/README_config IPP/router/TableInit.c
# IPP/router/router.c
# Wrapped by kent@sparky on Wed Nov 24 11:51:02 1993
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 4 (of 6)."'
if test -f 'IPP/config/ex1/16config' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/config/ex1/16config'\"
else
echo shar: Extracting \"'IPP/config/ex1/16config'\" \(2047 characters\)
sed "s/^X//" >'IPP/config/ex1/16config' <<'END_OF_FILE'
X# The config file is quite strict in terms of layout, Comments MUST start with a #
X# You cannot place comments anywhere you want...
X# You are allowed blank lines...
X# ONLY spaces are allowed as separators...
X# The FIRST thing you have to write is the address of the router.,
X
XAddress 16
X
X# The n you have to write the interface specification.. the thing begins with
X# a special keyword... otherwise it is too complicated.
X# The other thing is tha all parameters fit in one line... in the following order
X# Number LinkType Listen Parameters
X
XInterface 1 sock no localhost 1031
X
X#Interface 1 sock yes
XInterface 2 sock yes
XInterface 3 sock yes
XInterface 4 sock yes
X
X# Routing gets more complicated....
X# If a routing entry overwrite another one a WARNING message will follow !
X# Note how a routing entry does not know about interface technology
X#
X# The routing entry is more complicated... follows a list of explanation
X# 1) below/here/above This indicate if the route is for this level. down up
X# 2) number Indicate the hash table entry this route is for
X# 4) number Indicate the IPP address of next hop 1-254
X# 5) number Indicate the interface 0==none 1-n
X# 6) number Indicate the cost of a route 1-254
X
X# Ex: the following entry says that the route for host 11 in this level
X# is trought the host 11 itself and uses interface 1 with cost 1
XRoute Host 1 15 1 1
XRoute Host 2 15 1 1
XRoute Host 5 15 1 1
XRoute Host 10 15 1 1
X#Route Host 11 11 4 1
XRoute Host 15 15 1 1
X
X# this syas that route to subnet 10 can be done trough router 11 that is not
X# directly connected with a cost of 1
X# The fact that router 11 is not directly connected means that it is on
X# this same network.
X#Route Net 10 11 0 1
X
X# this says that a route to subnet 10 can be done via host 12 that is directly
X# connected but with a cost of 2
X# Being directly connected means that the next hop is subnet.router
X#Route Net 10 12 1 2
XRoute Net 1 2 0 2
X
X# A route to the parent network, the dummy entry is used to somplify
X# the parsing algorithms.
X#Route Parent dummy 12 1 2
X
END_OF_FILE
if test 2047 -ne `wc -c <'IPP/config/ex1/16config'`; then
echo shar: \"'IPP/config/ex1/16config'\" unpacked with wrong size!
fi
# end of 'IPP/config/ex1/16config'
fi
if test -f 'IPP/config/ex1/config' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/config/ex1/config'\"
else
echo shar: Extracting \"'IPP/config/ex1/config'\" \(2364 characters\)
sed "s/^X//" >'IPP/config/ex1/config' <<'END_OF_FILE'
X# The config file is quite strict in terms of layout, Comments MUST start with a #
X# You cannot place comments anywhere you want...
X# You are allowed blank lines...
X# ONLY spaces are allowed as separators...
X# The FIRST thing you have to write is the address of the router.,
X
XAddress 1.1
X
X# The n you have to write the interface specification.. the thing begins with
X# a special keyword... otherwise it is too complicated.
X# The other thing is tha all parameters fit in one line... in the following order
X# Number The number of this interface (0 not allowed)
X# Technology Can be sock, atm, ... (Only sock allowed now)
X# yes/no Says if the interface is a Listen interface or not
X# Parameters of the connect call in case the If is a calling interface
X
X#Interface 1 sock no localhost 1026
X
X#Interface 1 sock yes
X#Interface 2 sock yes
X#Interface 3 sock yes
XInterface 4 sock yes
X
X# Routing gets more complicated....
X# If a routing entry overwrite another one a WARNING message will follow !
X# Note how a routing entry does not know about interface technology
X#
X# The routing entry is more complicated... follows a list of explanation
X# 1) host/net/parent This indicate if the route is for this level. down up
X# 2) number Indicate the hash table entry this route is for
X# 4) number Indicate the IPP address of next hop 1-254
X# 5) number Indicate the interface 0==none 1-n
X# 6) number Indicate the cost of a route 1-254
X
X# Ex: the following entry says that the route for host 11 in this level
X# is trought the host 11 itself and uses interface 1 with cost 1
X# NOTE: Host route MUST have a directly connected next hop
X#Route Host 11 11 1 1
X#Route Host 3 3 1 1
X#Route Host 4 4 1 1
X#Route Host 5 5 1 1
X
X# this syas that route to subnet 10 can be done trough router 11 that is not
X# directly connected with a cost of 1
X# Being not directly connected means that you have to use other routers in this
X# same net to reache the desired one.
X#Route Net 10 11 0 1
X
X# this says that a route to subnet 10 can be done via host 12 that is directly
X# connected but with a cost of 2
X# Being directly connected means that the next hop is subnet.router
X#Route Net 10 12 1 2
X
X# A route to the parent network, the dummy entry is used to somplify
X# the parsing algorithms.
X# The fields are as follows, routing host, interface, cost
X#Route Parent dummy 1 1 2
X#Route Parent dummy 1 2 1
END_OF_FILE
if test 2364 -ne `wc -c <'IPP/config/ex1/config'`; then
echo shar: \"'IPP/config/ex1/config'\" unpacked with wrong size!
fi
# end of 'IPP/config/ex1/config'
fi
if test -f 'IPP/config/ex2/2config' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/config/ex2/2config'\"
else
echo shar: Extracting \"'IPP/config/ex2/2config'\" \(2335 characters\)
sed "s/^X//" >'IPP/config/ex2/2config' <<'END_OF_FILE'
X# The config file is quite strict in terms of layout, Comments MUST start with a #
X# You cannot place comments anywhere you want...
X# You are allowed blank lines...
X# ONLY spaces are allowed as separators...
X# The FIRST thing you have to write is the address of the router.,
X
XAddress 2
X
X# The n you have to write the interface specification.. the thing begins with
X# a special keyword... otherwise it is too complicated.
X# The other thing is tha all parameters fit in one line... in the following order
X# Number LinkType Listen Parameters
X
X#Interface 1 sock no localhost 4326
X#Interface 2 sock no localhost 4366
X
XInterface 1 sock yes
XInterface 2 sock yes
XInterface 3 sock yes
XInterface 4 sock yes
XInterface 5 sock yes
X
X# Routing gets more complicated....
X# If a routing entry overwrite another one a WARNING message will follow !
X# Note how a routing entry does not know about interface technology
X#
X# The routing entry is more complicated... follows a list of explanation
X# 1) below/here/above This indicate if the route is for this level. down up
X# 2) number Indicate the hash table entry this route is for
X# 4) number Indicate the IPP address of next hop 1-254
X# 5) number Indicate the interface 0==none 1-n
X# 6) number Indicate the cost of a route 1-254
X
X# Ex: the following entry says that the route for host 11 in this level
X# is trought the host 11 itself and uses interface 1 with cost 1
X# NOTE: ALL next hop of a host must be directly connected
X# NOTE: You should NOT setup a route for a calling host.
X
X# This is a multile route but NO loop since the other hosts are set ok
XRoute Host 7 3 2 1
XRoute Host 7 5 4 2
XRoute Host 7 4 3 2
X
X# Now a multiple route to host 8
XRoute Host 8 4 3 1
XRoute Host 8 5 4 3
XRoute Host 8 3 2 3
X
XRoute Host 9 5 4 1
X
X# this syas that route to subnet 10 can be done trough router 11 that is not
X# directly connected with a cost of 1
X# The fact that router 11 is not directly connected means that it is on
X# this same network.
X#Route Net 10 11 0 1
X
X# this says that a route to subnet 10 can be done via host 12 that is directly
X# connected but with a cost of 2
X# Being directly connected means that the next hop is subnet.router
X#Route Net 10 12 1 2
X#Route Net 1 1 1 2
X
X# A route to the parent network, the dummy entry is used to somplify
X# the parsing algorithms.
X#Route Parent dummy 12 1 2
X
END_OF_FILE
if test 2335 -ne `wc -c <'IPP/config/ex2/2config'`; then
echo shar: \"'IPP/config/ex2/2config'\" unpacked with wrong size!
fi
# end of 'IPP/config/ex2/2config'
fi
if test -f 'IPP/config/ex2/3config' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/config/ex2/3config'\"
else
echo shar: Extracting \"'IPP/config/ex2/3config'\" \(2330 characters\)
sed "s/^X//" >'IPP/config/ex2/3config' <<'END_OF_FILE'
X# The config file is quite strict in terms of layout, Comments MUST start with a #
X# You cannot place comments anywhere you want...
X# You are allowed blank lines...
X# ONLY spaces are allowed as separators...
X# The FIRST thing you have to write is the address of the router.,
X
XAddress 3
X
X# The n you have to write the interface specification.. the thing begins with
X# a special keyword... otherwise it is too complicated.
X# The other thing is tha all parameters fit in one line... in the following order
X# Number LinkType Listen Parameters
X
X#Interface 1 sock no localhost 4326
X
XInterface 1 sock yes
XInterface 2 sock yes
XInterface 3 sock yes
XInterface 4 sock no localhost 4366
XInterface 5 sock yes
X
X# Routing gets more complicated....
X# If a routing entry overwrite another one a WARNING message will follow !
X# Note how a routing entry does not know about interface technology
X#
X# The routing entry is more complicated... follows a list of explanation
X# 1) below/here/above This indicate if the route is for this level. down up
X# 2) number Indicate the hash table entry this route is for
X# 4) number Indicate the IPP address of next hop 1-254
X# 5) number Indicate the interface 0==none 1-n
X# 6) number Indicate the cost of a route 1-254
X
X# Ex: the following entry says that the route for host 11 in this level
X# is trought the host 11 itself and uses interface 1 with cost 1
X# NOTE: ALL next hop of a host must be directly connected
X# NOTE: You should NOT setup a route for a calling host.
XRoute Host 1 2 4 1
XRoute Host 2 2 4 1
XRoute Host 6 2 4 1
X
X# Multiple route to host 8 (With loops)
XRoute Host 8 4 2 1
XRoute Host 8 2 4 3
XRoute Host 8 5 3 3
X
X# This is a multiple router without looping
XRoute Host 9 5 3 1
XRoute Host 9 2 4 2
XRoute Host 9 4 2 2
X
X# this syas that route to subnet 10 can be done trough router 11 that is not
X# directly connected with a cost of 1
X# The fact that router 11 is not directly connected means that it is on
X# this same network.
X#Route Net 10 11 0 1
X
X# this says that a route to subnet 10 can be done via host 12 that is directly
X# connected but with a cost of 2
X# Being directly connected means that the next hop is subnet.router
X#Route Net 10 12 1 2
X#Route Net 1 1 1 2
X
X# A route to the parent network, the dummy entry is used to somplify
X# the parsing algorithms.
X#Route Parent dummy 12 1 2
X
END_OF_FILE
if test 2330 -ne `wc -c <'IPP/config/ex2/3config'`; then
echo shar: \"'IPP/config/ex2/3config'\" unpacked with wrong size!
fi
# end of 'IPP/config/ex2/3config'
fi
if test -f 'IPP/config/ex2/5config' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/config/ex2/5config'\"
else
echo shar: Extracting \"'IPP/config/ex2/5config'\" \(2311 characters\)
sed "s/^X//" >'IPP/config/ex2/5config' <<'END_OF_FILE'
X# The config file is quite strict in terms of layout, Comments MUST start with a #
X# You cannot place comments anywhere you want...
X# You are allowed blank lines...
X# ONLY spaces are allowed as separators...
X# The FIRST thing you have to write is the address of the router.,
X
XAddress 5
X
X# The n you have to write the interface specification.. the thing begins with
X# a special keyword... otherwise it is too complicated.
X# The other thing is tha all parameters fit in one line... in the following order
X# Number LinkType Listen Parameters
X
X#Interface 1 sock no localhost 4326
X
XInterface 1 sock yes
XInterface 2 sock no localhost 4366
XInterface 3 sock no localhost 4366
XInterface 4 sock no localhost 4366
XInterface 5 sock yes
X
X# Routing gets more complicated....
X# If a routing entry overwrite another one a WARNING message will follow !
X# Note how a routing entry does not know about interface technology
X#
X# The routing entry is more complicated... follows a list of explanation
X# 1) below/here/above This indicate if the route is for this level. down up
X# 2) number Indicate the hash table entry this route is for
X# 4) number Indicate the IPP address of next hop 1-254
X# 5) number Indicate the interface 0==none 1-n
X# 6) number Indicate the cost of a route 1-254
X
X# Ex: the following entry says that the route for host 11 in this level
X# is trought the host 11 itself and uses interface 1 with cost 1
X# NOTE: ALL next hop of a host must be directly connected
X# NOTE: You should NOT setup a route for a calling host.
XRoute Host 1 2 2 1
XRoute Host 2 2 2 1
XRoute Host 3 3 3 1
XRoute Host 4 4 4 1
XRoute Host 6 2 2 1
XRoute Host 7 3 3 1
X
X# Multiple route to host 8 with loops
XRoute Host 8 4 4 1
XRoute Host 8 2 2 3
XRoute Host 8 3 3 3
X
X# this syas that route to subnet 10 can be done trough router 11 that is not
X# directly connected with a cost of 1
X# The fact that router 11 is not directly connected means that it is on
X# this same network.
X#Route Net 10 11 0 1
X
X# this says that a route to subnet 10 can be done via host 12 that is directly
X# connected but with a cost of 2
X# Being directly connected means that the next hop is subnet.router
X#Route Net 10 12 1 2
X#Route Net 1 1 1 2
X
X# A route to the parent network, the dummy entry is used to somplify
X# the parsing algorithms.
X#Route Parent dummy 12 1 2
X
END_OF_FILE
if test 2311 -ne `wc -c <'IPP/config/ex2/5config'`; then
echo shar: \"'IPP/config/ex2/5config'\" unpacked with wrong size!
fi
# end of 'IPP/config/ex2/5config'
fi
if test -f 'IPP/ethernet/Tnet.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/ethernet/Tnet.c'\"
else
echo shar: Extracting \"'IPP/ethernet/Tnet.c'\" \(2900 characters\)
sed "s/^X//" >'IPP/ethernet/Tnet.c' <<'END_OF_FILE'
X/* -----------------------------------------------------------------------------
X * Ident: Tnet.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "ethernet.h"
X#include "func_defs.h"
X
Xstruct Debug dbg;
X
X/* This program tryes to simulate the behaviour of an ethernet interface
X * The simulation is more like a Tnet based net since each host has
X * Its own "wire"
X */
X
Xint main (int argc, char *argv[])
X {
X int c; /* The usual counter, no poit to have a long name */
X int error;
X struct timeval timeout;
X
X struct Ethernet eth;
X
X if ( DebugInit ( "localhost", "1234", "ethernet") ) exit (1);
X if ( Setup ( ð )) exit (1);
X
X printf ("ListeningAddress %s %d \n",eth.Host,eth.ListenPort );
X
X /* Then what it has to do is a select on the various lines and see what happens
X * It should select on the line that has the listen too.
X */
X
X for (;;)
X {
X FD_ZERO (&(eth.readfds)); /* Reset all bits */
X timeout.tv_sec = IDLE_TOUT; /* Timeout in seconds */
X timeout.tv_usec = 0; /* and no microseconds */
X
X /* We have to set the mask each time we come here... */
X for (c=0; c <ADDR_NUM; c++ ) if ( eth.IoFd[c] )
X FD_SET (eth.IoFd[c], ð.readfds);
X FD_SET (eth.ListenFd, ð.readfds);
X
X error = select (MAX_FILES, &(eth.readfds), NULL, NULL, &timeout);
X
X /* Done nothing, I got a timeout, let's write it down... */
X if ( error == 0 ) eth.Idle++;
X
X /* Good there is something to do, let's do it */
X if ( error > 0 ) EthIo ( ð );
X
X if ( error < 0 )
X {
X sprintf (dbg.msg,"ethernet: Select failed");
X DebugCall ( ERR_SELECT, DEBUG_CRITICAL );
X /* It may be a descriptor gone out, check for it ! */
X }
X
X } /* End of the newerending for */
X
X } /* End of the main program */
X
X
X
X
X
X/* -----------------------------------------------------------------------------
X * This function is in charge to set the system up.
X * If there are error it will report using the Debug function that uses the logd
X * daemon.
X * This function returns 0 if all is ok 1 otherwise.
X */
X
Xint Setup ( struct Ethernet *eth )
X {
X int c;
X
X /* Well, so far all ok... now it is time to set the ethernet data */
X /* first thing is to sett al those descriptors in the right way */
X for ( c=0; c<ADDR_NUM; c++ ) eth->IoFd[c]=0;
X
X /* The let's try to get alistening socket to work with */
X /* Error messages are sent to the logd */
X if ( Listen ( ð->ListenFd, eth->Host, ð->ListenPort ) )
X return (NOT_DONE);
X
X eth->Idle=0; /* This also has to be initialized */
X eth->BadPack=0; /* This also has to be initialized */
X eth->LostPack=0; /* This also has to be initialized */
X
X return (DONE);
X }
END_OF_FILE
if test 2900 -ne `wc -c <'IPP/ethernet/Tnet.c'`; then
echo shar: \"'IPP/ethernet/Tnet.c'\" unpacked with wrong size!
fi
# end of 'IPP/ethernet/Tnet.c'
fi
if test -f 'IPP/host/HostInit.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/host/HostInit.c'\"
else
echo shar: Extracting \"'IPP/host/HostInit.c'\" \(3328 characters\)
sed "s/^X//" >'IPP/host/HostInit.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------------------
X * Ident: HostInit.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <sys/time.h>
X#include <netinet/in.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "commands.h"
X#include "router.h"
X#include "host.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
Xint TableInit ( struct Host *hostdata );
X
X/* This is a host. It can only have one link
X * The link is setup at startup time by command line.
X */
X
Xint HostInit ( struct Host *hostdata )
X {
X char *Line;
X char *Cmd;
X char *Arg;
X char Null[2]={0};
X
X /* I must be shure that the tables are initilized properly */
X TableInit ( hostdata );
X
X /* Then first thing to do is to get my own address... */
X if ( GetAddress (&hostdata->Myaddr) ) return (NOT_DONE);
X
X /* Ok, now... we get a line and see what the key is */
X while ( (Line=ReadConfig(stdin)) != NULL )
X {
X if ((Cmd=strtok(Line,CMD_SEP))==NULL) { Cmd=Null; Arg=Null; }
X else Arg=Cmd+strlen(Cmd)+1;
X
X if ( strcasecmp (Cmd, CMD_INTERFACE) == 0 )
X SetInterface (hostdata, Arg);
X
X if ( strcasecmp (Cmd, CMD_ROUTER) == 0 )
X hostdata->Router = ipp_atoi(Arg);
X
X if ( strcasecmp (Cmd, CMD_TALKTO) == 0 )
X SetPeer ( hostdata, Arg );
X }
X
X return (DONE);
X }
X
Xint SetPeer ( struct Host *hostdata, char *Arg )
X {
X struct IPPaddr *Taddr;
X int c;
X
X Taddr = ipp_aton (Arg);
X if ( Taddr == NULL )
X {
X sprintf (dbg.msg,"SetPerr: Cannot conver to net address %s",Arg);
X DebugCall ( ERR_BADADDR, DEBUG_NOTICE );
X return (NOT_DONE);
X }
X
X for (c=0; c<PEER_MAX; c++ )
X {
X if ( hostdata->Peer[c].Peer.Al > 0 ) continue;
X ipp_AtoA ( &hostdata->Peer[c].Peer, Taddr );
X break;
X }
X
X return(DONE);
X }
X
Xint SetInterface ( struct Host *hostdata, char *Arg )
X {
X int EndPort; /* An integer indicating the end port to connect */
X char *Tech; /* Technology used for this link */
X char *EndNam; /* A string indicating the name of the endpoint(host) */
X char Null[2]={0};
X int Line;
X
X if ((Tech=strtok (Arg,CMD_SEP))==NULL) Tech=Null;
X if ((EndNam=strtok (NULL,CMD_SEP))==NULL) EndNam=Null;
X EndPort = ipp_atoi(strtok (NULL,CMD_SEP));
X
X if ( strcasecmp(Tech,SOCK_TECH_NAM) != 0 )
X {
X sprintf (dbg.msg,"SetInetrface: This technology is not supported %s",Tech);
X DebugCall ( ERR_NOTECH, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X
X if ( Connect ( EndNam, EndPort, &Line, &hostdata->Myaddr ) ) return (NOT_DONE);
X
X /* Ok we are connected now ! let's store the values ! */
X hostdata->NetFd = Line;
X
X return (DONE);
X }
X
X
Xint TableInit ( struct Host *hostdata )
X {
X int c;
X
X hostdata->PackId = 0;
X hostdata->BadPack = 0;
X hostdata->CurPeer = 0;
X
X for (c=0; c<PEER_MAX; c++ )
X {
X hostdata->Peer[c].Peer.Al = 0;
X hostdata->Peer[c].Freq = 0;
X hostdata->Peer[c].SndCount = 0;
X hostdata->Peer[c].RcvCount = 0;
X }
X
X return (DONE);
X }
X
END_OF_FILE
if test 3328 -ne `wc -c <'IPP/host/HostInit.c'`; then
echo shar: \"'IPP/host/HostInit.c'\" unpacked with wrong size!
fi
# end of 'IPP/host/HostInit.c'
fi
if test -f 'IPP/include/packet.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/include/packet.h'\"
else
echo shar: Extracting \"'IPP/include/packet.h'\" \(3232 characters\)
sed "s/^X//" >'IPP/include/packet.h' <<'END_OF_FILE'
X/* ----------------------------------------------------------------------
X * AUthor: Damiano Bolla, 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#ifndef PACKET_H
X#define PACKET_H
X
X
X#define PTYPE_DATA 1 /* The packet just contains data */
X#define PTYPE_PING 2 /* The packet request for a ping */
X#define PTYPE_RR 3 /* The packet is asking for ROute Record */
X
X/* This file defines the structure of a TEST IPP packet.
X * An IPP packet is very similar to a IP packet apart the fields
X * related to the addressing scheme.
X * A test IPP packet does not need information about resequencing or
X * window control it only needs routing information and a TTL.
X * To enhance the security of the system a simple checksum will be added
X */
X
X/* What follows is the structure that will hold a packet internally
X * This structure is slightly different from the way a packet is sent in the ne
X * since the internal rappresentation has to be fast instead the network
X * reppresentation has to be size efficient.
X * Note also that the network rappresentation IS in a network order
X * instead this rappresentation is in host order.
X * Note also that the network reppresentation has additional fields
X * packLen and Ckecksum that are NOT present here.
X */
Xstruct IPP
X {
X u_char Sl; /* Sender length */
X u_char SndAddr[ADDR_DEPTH+2]; /* The sender address, max */
X u_char Rl; /* Receiver length */
X u_char RcvAddr[ADDR_DEPTH+2]; /* The receiver address, max */
X u_char From; /* The host that just sent this packet */
X u_char Sender; /* The original host (In this domain) */
X u_char PackId; /* An Id for this domain.. */
X u_char NextRouter; /* Next router we have to reach */
X u_char NextHop; /* The Next address to reach (This net) */
X u_char Depth; /* The depth in the common tree */
X u_char TTL; /* The time to live of a packet */
X u_char Type; /* Packet Type, Ping, Route-Record... Data */
X u_short DataLen; /* The lenght of the data */
X char Data[IPP_DATA+2]; /* Tooo messy to have a pointer around.. */
X };
X
Xstruct IPPaddr
X {
X u_char Al; /* Address length */
X u_char Depth; /* The depth level of this address */
X u_char Addr[ADDR_DEPTH+2]; /* The address we are storing */
X };
X
X
X/* This part describes what a packet should look like when it is sent down the net
X * There will be a function that does the job of translating one rapp. to the
X * other once for alla functions.
X *
X
X 2 bytes Length of the entire packet BUT a max of IPP_DATA * 2
X 4 bits Length of the sender address (In bytes)
X 4 bits Length of the receiver address (In bytes)
X Max of 15 bytes The sender address
X Max of 15 bytes The receiver address
X 4 bits Unused
X 4 bits Depth where the addresses are common
X 1 u_char The From host, the one that just sent the packet
X 1 u_char The Sender host in this domain
X 1 u_char The packetId for this domain and the Sender host
X 1 u_char The address of the next router if any
X 1 u_char The next hop to reach
X 1 u_char The TIME to live of a packet (Initally 255)
X 1 u_char The pachet type
X 2 bytes The lenght of the data BUT a max of IPP_DATA
X Max IPP_DATA bytes
X 4 bytes Checksum unsigned long
X
X */
X
X#endif
END_OF_FILE
if test 3232 -ne `wc -c <'IPP/include/packet.h'`; then
echo shar: \"'IPP/include/packet.h'\" unpacked with wrong size!
fi
# end of 'IPP/include/packet.h'
fi
if test -f 'IPP/lib/route/FindParentRoute.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/lib/route/FindParentRoute.c'\"
else
echo shar: Extracting \"'IPP/lib/route/FindParentRoute.c'\" \(3144 characters\)
sed "s/^X//" >'IPP/lib/route/FindParentRoute.c' <<'END_OF_FILE'
X/* ---------------------------------------------------------------------------
X * Ident: FindParentRoute.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This tryes to find a route to the parent
X * It wants the routing table, the destination, and returns
X * what is the right next with the given depth and the interface.
X * NOTE: The interface returned is NOT a file descriptor it is anumber
X * indicating what interface to use !!!
X */
Xint FindParentRoute ( struct Routing *rinfo,
X u_char *NextRouter,
X u_char *NextHop,
X int *Interf )
X {
X struct NetEntry *Entry;
X struct HostEntry *EntryH;
X int UseThis;
X int Interface;
X int NextRo;
X
X /* If the following is true.. I have to use a Direct route */
X if ( *NextRouter )
X {
X Entry = &rinfo->parentdata;
X UseThis = Entry->Direct;
X if ( UseThis )
X {
X *Interf = Entry->Link[UseThis].Interface;
X *NextHop = Entry->Link[UseThis].Next;
X *NextRouter = NOT_USED;
X Entry->Link[UseThis].Cumulated += Entry->Link[UseThis].Cost;
X RouteNetMgr ( Entry );
X return (DONE);
X }
X else
X {
X sprintf (dbg.msg,"FindParentRoute: No direct route Parent");
X DebugCall ( ERR_BADROUTE, DEBUG_ALERT );
X return (NOT_DONE);
X }
X }
X
X
X /* If this Parent net has any route I can use it... */
X /* Othervise I have to say there is no route available... */
X Entry = &rinfo->parentdata;
X UseThis = Entry->Try;
X if ( !UseThis )
X {
X sprintf (dbg.msg,"FindParentRoute: No route at all to Parent");
X DebugCall ( ERR_BADROUTE, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X /* Let me see... is this a direct hop or am I using another host ? */
X /* NOTE: I have to increase the cost of this route anyway... */
X Interface = Entry->Link[UseThis].Interface;
X NextRo = Entry->Link[UseThis].Next;
X Entry->Link[UseThis].Cumulated += Entry->Link[UseThis].Cost;
X RouteNetMgr ( Entry );
X if ( Interface )
X {
X *NextRouter = NOT_USED;
X *NextHop = NextRo;
X *Interf = Interface;
X return (DONE);
X }
X
X /* nop. This is an indirect link. The next is not directly connected
X * Therefore I have to lookup THIS next in the HOST table and see...
X * NOTE: If the routing table IS correct you can still have the craziest
X * redundant configuration on earth.
X */
X EntryH = &rinfo->hostdata[NextRo];
X UseThis = EntryH->Direct;
X if ( !UseThis )
X {
X sprintf (dbg.msg,"FindParentRoute: No route to router %d",NextRo);
X DebugCall ( ERR_BADROUTE, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X *NextRouter = NextRo;
X *NextHop = EntryH->Link[UseThis].Next;
X *Interf = EntryH->Link[UseThis].Interface;
X EntryH->Link[UseThis].Cumulated += EntryH->Link[UseThis].Cost;
X RouteHostMgr ( EntryH );
X return (DONE);
X }
END_OF_FILE
if test 3144 -ne `wc -c <'IPP/lib/route/FindParentRoute.c'`; then
echo shar: \"'IPP/lib/route/FindParentRoute.c'\" unpacked with wrong size!
fi
# end of 'IPP/lib/route/FindParentRoute.c'
fi
if test -f 'IPP/lib/route/FindSubnetRoute.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/lib/route/FindSubnetRoute.c'\"
else
echo shar: Extracting \"'IPP/lib/route/FindSubnetRoute.c'\" \(3418 characters\)
sed "s/^X//" >'IPP/lib/route/FindSubnetRoute.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------------------
X * Ident: FindSubnetRoute.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This tryes to find a route to the desired network
X * It wants the routing table, the destination, and returns
X * what is the right next with the given depth and the interface.
X * NOTE: The interface returned is NOT a file descriptor it is anumber
X * indicating what interface to use !!!
X * NOTE: This ONLY find a route to a network
X */
Xint FindSubnetRoute ( struct Routing *rinfo,
X u_char Dest,
X u_char *NextRouter,
X u_char *NextHop,
X int *Interf )
X {
X struct NetEntry *Entry;
X struct HostEntry *EntryH;
X int UseThis;
X int Interface;
X int NextRo;
X
X /* If the following is true ... it means that I have to find a DIRECT
X * route to the network, since I am the second router hop to a network
X * NOTE: The fact that NextRouter is really me has been checked above
X */
X if ( *NextRouter )
X {
X Entry = &rinfo->netdata[Dest];
X UseThis = Entry->Direct;
X if ( UseThis )
X {
X *Interf = Entry->Link[UseThis].Interface;
X *NextHop = Entry->Link[UseThis].Next;
X *NextRouter = NOT_USED;
X Entry->Link[UseThis].Cumulated += Entry->Link[UseThis].Cost;
X RouteNetMgr ( Entry );
X return (DONE);
X }
X else
X {
X sprintf (dbg.msg,"FindSubnetRoute: Cannot find direct route to %d",Dest);
X DebugCall ( ERR_BADROUTE, DEBUG_ALERT );
X return (NOT_DONE);
X }
X }
X
X /* If this Net has any route I can use it...
X * Othervise I have to say there is no route available...
X */
X Entry = &rinfo->netdata[Dest];
X UseThis = Entry->Try;
X if ( !UseThis )
X {
X sprintf (dbg.msg,"FindSubnetRoute: No kind of route to %d",Dest);
X DebugCall ( ERR_BADROUTE, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X /* Let me see... is this a direct hop or am I using another host ?
X * NOTE: I have to increase the cost of this route anyway...
X */
X Interface = Entry->Link[UseThis].Interface;
X NextRo = Entry->Link[UseThis].Next;
X Entry->Link[UseThis].Cumulated += Entry->Link[UseThis].Cost;
X RouteNetMgr ( Entry );
X if ( Interface )
X {
X /* Wow ! a nice direct link ! */
X *NextRouter = NOT_USED;
X *NextHop = NextRo;
X *Interf = Interface;
X return (DONE);
X }
X
X /* nop. This is an indirect link. The next is not directly connected
X * Therefore I have to lookup THIS next in the HOST table and see...
X * NOTE: If the routing table IS correct you can still have the craziest
X * redundant configuration on earth.
X */
X EntryH = &rinfo->hostdata[NextRo];
X UseThis = EntryH->Direct;
X if ( !UseThis )
X {
X sprintf (dbg.msg,"FindSubnetRoute: No direct to router %d",NextRo);
X DebugCall ( ERR_BADROUTE, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X *NextRouter = NextRo;
X *NextHop = EntryH->Link[UseThis].Next;
X *Interf = EntryH->Link[UseThis].Interface;
X EntryH->Link[UseThis].Cumulated += EntryH->Link[UseThis].Cost;
X RouteHostMgr ( EntryH );
X return (DONE);
X }
END_OF_FILE
if test 3418 -ne `wc -c <'IPP/lib/route/FindSubnetRoute.c'`; then
echo shar: \"'IPP/lib/route/FindSubnetRoute.c'\" unpacked with wrong size!
fi
# end of 'IPP/lib/route/FindSubnetRoute.c'
fi
if test -f 'IPP/lib/route/RouteMgr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/lib/route/RouteMgr.c'\"
else
echo shar: Extracting \"'IPP/lib/route/RouteMgr.c'\" \(2648 characters\)
sed "s/^X//" >'IPP/lib/route/RouteMgr.c' <<'END_OF_FILE'
X/* ---------------------------------------------------------------------------
X * Ident: RouteMgr.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
X/* This function is the one that can be offlined.
X * What it does is to find what is the next "best" Link to try for a route
X * It uses the cumulated cost as a means. It also has the job of selecting
X * a "valid" link in case one has been shut down.
X * Note the complexity interoduced by the direct link concept
X */
X
Xint RouteNetMgr ( struct NetEntry *route )
X {
X int c;
X int Try;
X int Direct;
X u_int Cur; /* The current cumulated */
X
X /* I dont really care about his, should I ? :-) Damiano */
X if ( route==NULL ) return (DONE);
X
X /* Warning !!! algoritmo Extra stupido !!! NON sottrae il costo.. */
X /* Double WARNING il valore di Cur e' passibile di overlow... */
X
X Cur = 1234567; /* We start with a big cost and then go down */
X Try = NOT_USED; /* Assume no link is available */
X Direct = NOT_USED; /* The same for the direct route */
X
X for (c=1; c<=ROUTE_MAX; c++ )
X {
X if ( route->Link[c].Next == NOT_USED ) continue;
X
X /* I NEEED to find a direct link anyway if I dont' have one... */
X if ( !Direct && route->Link[c].Interface ) Direct = c;
X
X if ( route->Link[c].Cumulated <= Cur )
X {
X Cur=route->Link[c].Cumulated;
X if ( route->Link[c].Interface ) Direct = c;
X Try=c;
X }
X }
X
X route->Try = Try;
X route->Direct = Direct;
X
X return (DONE);
X }
X
Xint RouteHostMgr ( struct HostEntry *route )
X {
X int c;
X int Direct;
X int Another;
X u_int Cur; /* The current cumulated */
X
X /* I dont really care about his, should I ? :-) Damiano */
X if ( route==NULL ) return (DONE);
X
X /* Warning !!! algoritmo Extra stupido !!! NON sottrae il costo.. */
X /* Double WARNING il valore di Cur e' passibile di overlow... */
X
X Cur = 1234567; /* We start with a big cost and then go down */
X Direct = NOT_USED; /* The same for the direct route */
X Another = NOT_USED; /* Assume no link is available */
X
X for (c=1; c<=ROUTE_MAX; c++ )
X {
X if ( route->Link[c].Next == NOT_USED ) continue;
X
X if ( route->Link[c].Cumulated < Cur )
X {
X Cur=route->Link[c].Cumulated;
X Another=Direct;
X Direct=c;
X }
X }
X
X route->Direct = Direct;
X route->Another = Another;
X
X return (DONE);
X }
X
END_OF_FILE
if test 2648 -ne `wc -c <'IPP/lib/route/RouteMgr.c'`; then
echo shar: \"'IPP/lib/route/RouteMgr.c'\" unpacked with wrong size!
fi
# end of 'IPP/lib/route/RouteMgr.c'
fi
if test -f 'IPP/lib/utils/Connect.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/lib/utils/Connect.c'\"
else
echo shar: Extracting \"'IPP/lib/utils/Connect.c'\" \(2444 characters\)
sed "s/^X//" >'IPP/lib/utils/Connect.c' <<'END_OF_FILE'
X/* ---------------------------------------------------------------------------------
X * Ident: Connect.c
X * Author: Damiano Bolla
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <unistd.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <sys/time.h>
X#include <netinet/in.h>
X#include "defs.h"
X#include "packet.h"
X#include "debug.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This function tryes to create a new socket and connet it to the given
X * address and port.
X * It will deal with errors in a distributed way and will return
X * DONE if all is fine (0) or NOT_DONE otherwise.
X * The connection will send to the other side my address.
X */
X
Xint Connect ( char *host, u_short port, int *sock, struct IPPaddr *Myaddr )
X {
X struct sockaddr_in to_where;
X struct hostent *host_data;
X int newsocket;
X char Buff[CONF_LLEN+2];
X
X host_data = gethostbyname ( host );
X if ( host_data == NULL )
X {
X sprintf (dbg.msg,"Connect: Cannot get address of %s ",host);
X DebugCall ( ERR_NOHOST, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X newsocket = socket ( AF_INET, SOCK_STREAM, 0);
X if ( newsocket < 0 )
X {
X sprintf (dbg.msg,"Connect: Cannot Create a new socket to be used ");
X DebugCall ( ERR_NOSOCK, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X /* Good, let's fill the destination where I want to connect */
X to_where.sin_family = AF_INET;
X to_where.sin_port = htons(port);
X memcpy ((char *)&to_where.sin_addr.s_addr ,host_data->h_addr_list[0] ,4 );
X memset ((char*)&to_where.sin_zero, 0, sizeof(to_where.sin_zero));
X
X /* NOTE: This call may block... what can I do ? Damiano */
X if ( connect ( newsocket, (struct sockaddr *)&to_where, sizeof(to_where)) )
X {
X sprintf (dbg.msg,"Connect: Cannot connect to %s port %d ",host,port);
X DebugCall ( ERR_BADCONN, DEBUG_ALERT );
X close (newsocket); /* Remembar this... */
X return (NOT_DONE);
X }
X
X /* Ok, the socket is connected and is up... should I mark it non block ? */
X /* Not for the moment.. . let me try something Damiano */
X *sock = newsocket;
X
X /* What follows is a bit of a quick hack... I rely on the watchdog to
X * catch possible lockings... Damiano
X */
X sprintf (Buff,"Address %s \n",ipp_ntoa(Myaddr));
X write (newsocket, Buff, strlen(Buff));
X
X return (DONE);
X }
END_OF_FILE
if test 2444 -ne `wc -c <'IPP/lib/utils/Connect.c'`; then
echo shar: \"'IPP/lib/utils/Connect.c'\" unpacked with wrong size!
fi
# end of 'IPP/lib/utils/Connect.c'
fi
if test -f 'IPP/lib/utils/Debug.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/lib/utils/Debug.c'\"
else
echo shar: Extracting \"'IPP/lib/utils/Debug.c'\" \(3218 characters\)
sed "s/^X//" >'IPP/lib/utils/Debug.c' <<'END_OF_FILE'
X/* -----------------------------------------------------------------------------
X * Ident: Debug.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <unistd.h>
X#include <memory.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <netinet/in.h>
X#include <signal.h>
X#include <sys/utsname.h>
X#include <errno.h>
X#include "defs.h"
X#include "debug.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This function is in charge to send debug information to the logd daemon.
X * It requests various things to be filled.
X * It does not return errors since I would not know how to handle them.
X */
X
Xvoid DebugCall ( int ErrType, int ErrLevel )
X {
X struct sockaddr_in address;
X int address_len;
X int packet_len;
X int error;
X
X dbg.type = ErrType;
X dbg.debug_level = ErrLevel;
X
X /* If the debug level is not appropriate do nothing */
X if ( dbg.current_level > dbg.debug_level ) return;
X
X sprintf (dbg.MsgBuff,"Program %s\nIdent %s\nPid %d\nErrType %d\nErrLevel %d\nErrMsg %s",
X dbg.prog, dbg.ident, dbg.pid, dbg.type, dbg.debug_level, dbg.msg );
X
X address.sin_family = SOCK_DGRAM;
X address.sin_port = htons(dbg.logd_port);
X address.sin_addr.s_addr = dbg.logd_host;
X memset (address.sin_zero, 0, sizeof(address.sin_zero));
X
X address_len = sizeof (struct sockaddr_in);
X packet_len = strlen (dbg.MsgBuff); /* Do not sent the zero at the end */
X error = sendto (dbg.send_socket, /* The socket from where to get data */
X dbg.MsgBuff, /* Destination buffer */
X packet_len, /* Size of the buffer */
X 0, /* Options */
X (struct sockaddr *)&address, /* A place where to store */
X address_len /* The length of address */
X );
X
X /* After I sent it I have to NULL the message */
X dbg.msg[0]=0;
X }
X
X/* ----------------------------------------------------------------------------
X * This function set up the debug system.
X * Since the debug system is THE MOST VITAL PART and HAS to be the first
X * to be initialized if there is ANY error here the program termintes.
X * Program termination is anyway duty of the caller.
X */
X
Xint DebugInit ( char *logd_host, char *logd_port, char *prog )
X {
X struct hostent *host;
X u_short port;
X
X host=gethostbyname(logd_host);
X if ( host==NULL )
X {
X fprintf (stderr,"DebugInit: Cannot find the loghost %s \n",logd_host);
X return (NOT_DONE);
X }
X
X if ( host->h_length < 0 )
X {
X fprintf (stderr,"DebugInit: Cannot find address for loghost %s \n",logd_host);
X return (NOT_DONE);
X }
X
X memcpy ((char *)&dbg.logd_host ,host->h_addr_list[0] ,4 );
X
X port=ipp_atoi(logd_port);
X dbg.logd_port=port; /* Internal data are in internal format */
X
X /* I create a working socket now to be shure that I have when is needed */
X dbg.send_socket = socket ( PF_INET, SOCK_DGRAM, 0);
X if ( dbg.send_socket < 0 )
X {
X fprintf (stderr,"DebugInit: Cannot create a working socket \n");
X return (NOT_DONE);
X }
X
X strncpy (dbg.prog, prog, ERR_LEN);
X dbg.ident[0]=0;
X dbg.pid = getpid();
X dbg.type=ERR_OK;
X dbg.current_level=DEBUG_LEVEL;
X dbg.msg[0]=0;
X return (DONE);
X }
X
X
END_OF_FILE
if test 3218 -ne `wc -c <'IPP/lib/utils/Debug.c'`; then
echo shar: \"'IPP/lib/utils/Debug.c'\" unpacked with wrong size!
fi
# end of 'IPP/lib/utils/Debug.c'
fi
if test -f 'IPP/monitor/monitor.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/monitor/monitor.c'\"
else
echo shar: Extracting \"'IPP/monitor/monitor.c'\" \(2282 characters\)
sed "s/^X//" >'IPP/monitor/monitor.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------------------
X * Ident: monitor.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <sys/time.h>
X#include <netinet/in.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
X#define STDIN 0
X
Xstruct Debug dbg;
X
X/* This is a monitor. It can only have one link
X * The link is setup at startup time by command line.
X * This is an interactive monitor.
X * It waits for you to type an address and a message and whow a message
X * sent to his host.
X */
X
Xint main ( int argc, char *argv[] )
X {
X int error;
X int talksock;
X
X struct IPPaddr myaddr; /* My address.. */
X struct IPPaddr *Taddr;
X int NextHop; /* Address of next hop... */
X u_char PackId=0;
X
X int EthPort;
X char TmpBuff[CONF_LLEN+2];
X
X fd_set readfds;
X
X /* First thing to do is to setup the debugging unit... */
X if ( DebugInit ( "localhost", "1234", "Monitor") ) return (1);
X
X /* Then I have to wire up the system... */
X printf ("Port for wiring up > ");fflush (stdout);
X scanf ("%d",&EthPort);
X
X printf ("My IPP address in full > ");fflush (stdout);
X while (TtyGets (TmpBuff,CONF_LLEN), strlen(TmpBuff) == 0);
X Taddr = ipp_aton(TmpBuff);
X if ( Taddr == NULL ) exit (0);
X ipp_AtoA (&myaddr, Taddr);
X
X printf ("Address of router, single byte > "); fflush (stdout);
X scanf ("%d",&NextHop);
X
X if ( Connect ( "localhost", EthPort, &talksock, &myaddr ) ) return (1);
X
X strcpy (dbg.ident, ipp_ntoa(&myaddr));
X
X for (;;)
X {
X FD_ZERO (&readfds); /* Reset all bits */
X
X /* We have to set the mask each time we come here... */
X FD_SET (STDIN, &readfds);
X FD_SET (talksock, &readfds);
X
X error = select (MAX_FILES, &readfds, NULL, NULL, NULL);
X
X if ( error <= 0 ) continue;
X
X if ( FD_ISSET (STDIN, &readfds ) )
X if ( Send ( &myaddr, talksock, NextHop, &PackId ) ) return (0);
X
X if ( FD_ISSET (talksock, &readfds ) )
X if ( Receive ( &myaddr, talksock, NextHop ) ) return (0);
X }
X }
END_OF_FILE
if test 2282 -ne `wc -c <'IPP/monitor/monitor.c'`; then
echo shar: \"'IPP/monitor/monitor.c'\" unpacked with wrong size!
fi
# end of 'IPP/monitor/monitor.c'
fi
if test -f 'IPP/router/ParseData.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/router/ParseData.c'\"
else
echo shar: Extracting \"'IPP/router/ParseData.c'\" \(2774 characters\)
sed "s/^X//" >'IPP/router/ParseData.c' <<'END_OF_FILE'
X/* --------------------------------------------------------------------------
X * Ident: ParseData.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "commands.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This function parse the data inside a packet and do what requested.
X * The destination address and sender address has to be changed !!
X */
Xint ParseData ( struct Routing *rinfo, struct IPP *ipp, int *Sendit )
X {
X struct IPPaddr Receiver;
X char *Command;
X char *Argument;
X char *Params;
X char Null[2]={0};
X
X /* First thing to make shure is that there is a zero at the end of the data */
X ipp->Data[ipp->DataLen] = 0;
X
X /* Note the strtok breaking string, it is quite complex in a way */
X if ((Command=strtok(ipp->Data, CMD_SEP))==NULL) Command=Null;
X if ((Argument=strtok(NULL,CMD_SEP))==NULL) { Argument=Null; Params=Null; }
X else Params = Argument+strlen(Argument)+1;
X
X /* Now I have to transform the current sender as the receiver of the packet */
X ipp_StoA (ipp, &Receiver);
X if ( SetPackAddr (ipp, &rinfo->MyAddr, &Receiver ) )
X {
X sprintf (dbg.msg,"ParseData: Cannot set packet address ");
X DebugCall ( ERR_BADADDR, DEBUG_ALERT );
X *Sendit = FALSE;
X return (NOT_DONE);
X }
X
X if ( strcasecmp (Command,CMD_SHOW) == 0 )
X {
X if (strcasecmp (Argument, CMD_ROUTE) == 0 )
X ShowRoute ( rinfo, ipp->Data, IPP_DATA);
X if (strcasecmp (Argument, CMD_INTERFACE) == 0 )
X ShowInterface ( rinfo, ipp->Data, IPP_DATA);
X if (strcasecmp (Argument, CMD_STAT) == 0 )
X ShowStat ( rinfo, ipp->Data, IPP_DATA);
X ipp->DataLen = strlen(ipp->Data);
X *Sendit = TRUE;
X return (DONE);
X }
X
X if ( strcasecmp (Command,CMD_SET) == 0 )
X {
X int Errcode;
X Errcode = DONE;
X
X if (strcasecmp (Argument, CMD_ROUTE) == 0 )
X Errcode = RouteAdd ( rinfo, Params );
X if (strcasecmp (Argument, CMD_INTERFACE) == 0 )
X Errcode = SetInterface ( rinfo, Params );
X if (strcasecmp (Argument, CMD_DEBUG) == 0 )
X dbg.current_level = ipp_atoi (Params);
X
X if ( Errcode == DONE ) sprintf (ipp->Data,"Done ");
X else sprintf (ipp->Data,"Failed" );
X
X ipp->DataLen = strlen(ipp->Data);
X *Sendit = TRUE;
X return (DONE);
X }
X
X /* The following may be a bit drasitic... */
X if ( strcasecmp (Command,CMD_EXIT) == 0 ) exit (0);
X
X sprintf (dbg.msg,"ParseData: I was expec. a comm. got %s ",Command);
X DebugCall ( ERR_NOCOMM, DEBUG_ALERT );
X *Sendit = FALSE;
X return (DONE);
X }
END_OF_FILE
if test 2774 -ne `wc -c <'IPP/router/ParseData.c'`; then
echo shar: \"'IPP/router/ParseData.c'\" unpacked with wrong size!
fi
# end of 'IPP/router/ParseData.c'
fi
if test -f 'IPP/router/ParsePack.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/router/ParsePack.c'\"
else
echo shar: Extracting \"'IPP/router/ParsePack.c'\" \(2920 characters\)
sed "s/^X//" >'IPP/router/ParsePack.c' <<'END_OF_FILE'
X/* -----------------------------------------------------------------------------
X * Ident: ParsePack.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This function has a packet and tryes to determine what to do with it.
X * Some things have to be done according to the packet type.
X * Some others depending on the data in the packet.
X */
X
Xint ParsePack ( struct Routing *rinfo, struct IPP *ipp, int *Sendit )
X {
X struct IPPaddr Dest;
X u_char Mylastbyte;
X
X /* I get this so things get a bit simpler... */
X Mylastbyte = rinfo->MyAddr.Addr[rinfo->MyAddr.Al -1];
X
X /* I now should ckeck if this packet has as "next" relally me */
X /* Finish this part when the host has a routing table Damiano */
X if ( ipp->NextHop != Mylastbyte )
X {
X sprintf (dbg.msg,"ParsePack: The received Next is %d",ipp->NextHop);
X DebugCall ( ERR_BADNEXT, DEBUG_NOTICE );
X /* I continue anyway... it is not too bad... */
X }
X
X /* Ok, it is a right packet, now what does it ask me to do ?? */
X /* The next one does NOT care if the receiver is ME or not... */
X if ( ipp->Type == PTYPE_RR )
X {
X /* I have to be shure there is a null at the end... */
X ipp->Data[ipp->DataLen] = 0;
X if ( RecordRoute ( &rinfo->MyAddr, ipp->Data, IPP_DATA ) )
X {
X *Sendit = FALSE;
X return (NOT_DONE);
X }
X
X /* I do not appear to be the Sender of this packet... therefore */
X /* I do not need to set the sender byte */
X ipp->DataLen = strlen(ipp->Data);
X *Sendit = TRUE;
X return (DONE);
X }
X
X /* BUT the following DO care if the receiver is ME !!! I better check then */
X ipp_RtoA (ipp, &Dest );
X if ( AddressMatch ( &rinfo->MyAddr, &Dest, ipp->Depth ) == FALSE )
X {
X /* The packet is not for me.. baaa :-), I just have to forward it ! */
X *Sendit = TRUE;
X return (DONE);
X }
X
X /* Here I KNOW that the packet IS for me !!!
X * I then know that I MUST set to null the information regarding the
X * NextHop and NetRouter
X */
X ipp->From = NOT_USED;
X ipp->Sender = Mylastbyte;
X ipp->PackId = ++rinfo->PackId;
X ipp->NextHop = NOT_USED;
X ipp->NextRouter = NOT_USED;
X
X if ( ipp->Type == PTYPE_PING )
X {
X sprintf (dbg.msg,"ParsePack: PING function not done ");
X DebugCall ( ERR_NOTIMPL, DEBUG_ALERT );
X *Sendit = FALSE;
X return (DONE);
X }
X
X if ( ipp->Type == PTYPE_DATA )
X {
X ParseData ( rinfo, ipp, Sendit );
X return (DONE);
X }
X
X sprintf (dbg.msg,"ParsePack: Unknown packet type %d ",ipp->Type);
X DebugCall ( ERR_NOTIMPL, DEBUG_ALERT );
X *Sendit = FALSE;
X return (DONE);
X }
X
END_OF_FILE
if test 2920 -ne `wc -c <'IPP/router/ParsePack.c'`; then
echo shar: \"'IPP/router/ParsePack.c'\" unpacked with wrong size!
fi
# end of 'IPP/router/ParsePack.c'
fi
if test -f 'IPP/router/ProcessPack.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/router/ProcessPack.c'\"
else
echo shar: Extracting \"'IPP/router/ProcessPack.c'\" \(3066 characters\)
sed "s/^X//" >'IPP/router/ProcessPack.c' <<'END_OF_FILE'
X/* -------------------------------------------------------------------------
X * Ident: ProcessPack.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
Xextern struct Debug dbg;
X
X/* This function knows that there is apacket waiting, gets it,
X * And then do whatwver is needed
X * At the moment only TCp is supported...
X */
X
Xint ProcessPack ( struct Routing *rinfo, int RcvIf )
X {
X struct IPP ipp; /* The working packet buffer */
X struct IPPaddr Dest;
X u_char NextRo;
X u_char NextHo;
X int Eof;
X int SendIt;
X int SndIf;
X
X Eof = FALSE;
X SendIt = FALSE;
X
X if ( RcvPack ( &ipp, rinfo->ifdata[RcvIf].Line, &Eof ) )
X {
X if ( Eof ) CloseIf ( rinfo, RcvIf );
X rinfo->BadCount++;
X return (NOT_DONE);
X }
X
X /* Let's update the statistics... one more packet received.. */
X rinfo->ifdata[RcvIf].Received++;
X
X /* Now.. do I have seen this packet already ?? */
X if ( SeenAlready ( rinfo->seendata, ipp.Sender, ipp.PackId ))
X {
X rinfo->LoopCount++;
X sprintf (dbg.msg,"ProcessPack: Packet From %d Id %d already seen",ipp.Sender,ipp.PackId);
X DebugCall ( ERR_TTL, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X
X /* The ttl is defined as an u_char, therefore it cannot go below zero */
X if ( ipp.TTL-- == 0 )
X {
X rinfo->TTLCount++;
X sprintf (dbg.msg,"ProcessPack: Packet TTL is ZERO");
X DebugCall ( ERR_TTL, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X /* Now I have to see what the packet wants to do and then do it
X * If the resulting packet need to be sent I will set the flag SendIt
X * This part will check if the packet is for me and do things...
X * If this part changes the destination it MUST zero the NextRouter and
X * NextHop field in the packet
X */
X if ( ParsePack ( rinfo, &ipp, &SendIt ) )
X {
X sprintf (dbg.msg,"ProcessPack: Could not parse a packet ");
X DebugCall ( ERR_BADPACK, DEBUG_ALERT );
X return (NOT_DONE);
X }
X
X /* Nothing mutch to do if we don't have to send the resulting packet */
X if ( SendIt == FALSE ) return (DONE);
X
X /* I have to get the destination again the ParsePack may have changed it */
X ipp_RtoA (&ipp, &Dest );
X sprintf (dbg.msg,"ProcessPack: Finding route to %s",ipp_ntoa(&Dest));
X DebugCall ( ERR_MSG, DEBUG_TEXT );
X
X if ( FindRoute ( rinfo, &ipp, &SndIf) )
X {
X sprintf (dbg.msg,"ProcessPack: No route to %s",ipp_ntoa(&Dest));
X DebugCall ( ERR_NOROUTE, DEBUG_NOTICE );
X return (NOT_DONE);
X }
X
X /* What remains is just to send it... */
X Eof = FALSE;
X if ( SndPack ( &ipp, rinfo->ifdata[SndIf].Line, &Eof ) )
X {
X if ( Eof ) CloseIf ( rinfo, SndIf );
X rinfo->BadCount++;
X return (NOT_DONE);
X }
X
X /* Some more statistics... */
X rinfo->ifdata[SndIf].Sent++;
X
X return (DONE);
X }
X
END_OF_FILE
if test 3066 -ne `wc -c <'IPP/router/ProcessPack.c'`; then
echo shar: \"'IPP/router/ProcessPack.c'\" unpacked with wrong size!
fi
# end of 'IPP/router/ProcessPack.c'
fi
if test -f 'IPP/router/README_config' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/router/README_config'\"
else
echo shar: Extracting \"'IPP/router/README_config'\" \(2757 characters\)
sed "s/^X//" >'IPP/router/README_config' <<'END_OF_FILE'
X# This is an example of a config file.
X# The config file is quite strict in terms of layout, Comments MUST start with a #
X# You cannot place comments anywhere you want...
X# You are allowed blank lines...
X# ONLY spaces are allowed as separators...
X# The FIRST thing you have to write is the address of the router.,
X# Addresses are the FULL address of this router Ex: Address 1.2.3
X
XAddress 2
X
X# Then you have to write the interface specification.. the thing begins with
X# a special keyword... otherwise it is too complicated.
X# The other thing is tha all parameters fit in one line... in the following order
X# 1) Number indicating which interface you are setting
X# 2) Technology of this interface
X# 3) Yes/no Is this interface a listening interface or not ?
X# 4) The parameters for a NOT listening interface to connect to the other end
X# In this case the host and the port to connect to.
X
X#Interface 1 sock no localhost 4326
X#Interface 2 sock no localhost 4366
X
XInterface 1 sock yes
XInterface 2 sock yes
XInterface 3 sock yes
XInterface 4 sock yes
X
X# Follows the routing information
X# If a routing entry overwrite another one a WARNING message will follow !
X# Note how a routing entry does not know about interface technology
X#
X# The routing entry is more complicated... follows a list of explanation
X# 1) host/net/parent This indicate what this route is
X# 2) number Indicate the direct table entry this route is for
X# 4) number Indicate the IPP address of next hop 1-254
X# 5) number Indicate the interface 0==none 1-n
X# 6) number Indicate the cost of a route 1-254
X
X# Ex: the following entry says that the route for host 11 in this domain
X# is trought the host 11 itself and uses interface 1 with cost 1
X#Route Host 11 11 1 1
X
X# NOTE: ALL next hop of a host must be directly connected
X# NOTE: You should NOT setup a route for a calling host since such route gets
X# created when the calling host actually connect to the router
X# Follows some more routing examples
X
X#Route Host 5 15 1 1
X# Route Host 10 10 2 1
X#Route Host 11 15 1 1
X#Route Host 15 15 1 1
X#Route Host 16 15 1 1
X
X# this syas that route to subnet 10 can be done trough router 11 that is not
X# directly connected with a cost of 1
X# The fact that router 11 is not directly connected means that it is a distant router
X# in this domain for subnet 10
X#Route Net 10 11 0 1
X
X# this says that a route to subnet 10 can be done via host 12 that is directly
X# connected but with a cost of 2
X# NOTE: The next (in this case 12) is the address of the destination router in the subnet.
X#Route Net 10 12 1 2
X
X# A route to the parent network, the dummy entry is used to somplify
X# the parsing algorithm.
X# Apart this it follows the same structure as the subnet routing entry.
X#Route Parent dummy 12 1 2
X
END_OF_FILE
if test 2757 -ne `wc -c <'IPP/router/README_config'`; then
echo shar: \"'IPP/router/README_config'\" unpacked with wrong size!
fi
# end of 'IPP/router/README_config'
fi
if test -f 'IPP/router/TableInit.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/router/TableInit.c'\"
else
echo shar: Extracting \"'IPP/router/TableInit.c'\" \(2513 characters\)
sed "s/^X//" >'IPP/router/TableInit.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------------
X * Ident: TableInit.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
X/* This function initializes the routing tables to null.
X * It cannot fails since all data is already allocated...
X */
X
Xvoid TableInit ( struct Routing *rinfo )
X {
X int c;
X int d;
X
X for (c=0; c<ADDR_NUM; c++ )
X {
X rinfo->hostdata[c].Direct = NOT_USED;
X rinfo->hostdata[c].Another = NOT_USED;
X for (d=0; d<=ROUTE_MAX; d++)
X {
X rinfo->hostdata[c].Link[d].Next = NOT_USED;
X rinfo->hostdata[c].Link[d].Interface = NOT_USED;
X rinfo->hostdata[c].Link[d].Cost = NOT_USED;
X rinfo->hostdata[c].Link[d].Cumulated = NOT_USED;
X rinfo->hostdata[c].Link[d].Flag = NOT_USED;
X }
X }
X
X for (c=0; c<ADDR_NUM; c++ )
X {
X rinfo->netdata[c].Try = NOT_USED;
X rinfo->netdata[c].Direct = NOT_USED;
X for (d=0; d<=ROUTE_MAX; d++)
X {
X rinfo->netdata[c].Link[d].Next = NOT_USED;
X rinfo->netdata[c].Link[d].Interface = NOT_USED;
X rinfo->netdata[c].Link[d].Cost = NOT_USED;
X rinfo->netdata[c].Link[d].Cumulated = NOT_USED;
X rinfo->netdata[c].Link[d].Flag = NOT_USED;
X }
X }
X
X for (c=0; c<ADDR_NUM; c++ )
X {
X for (d=0; d<ADDR_NUM; d++)
X {
X rinfo->seendata[c][d].Sec=NOT_USED;
X }
X }
X
X rinfo->parentdata.Try = NOT_USED;
X rinfo->parentdata.Direct = NOT_USED;
X for (d=0; d<=ROUTE_MAX; d++)
X {
X rinfo->parentdata.Link[d].Next = NOT_USED;
X rinfo->parentdata.Link[d].Interface = NOT_USED;
X rinfo->parentdata.Link[d].Cost = NOT_USED;
X rinfo->parentdata.Link[d].Cumulated = NOT_USED;
X rinfo->parentdata.Link[d].Flag = NOT_USED;
X }
X
X /* The best way to set an address to "NULL" is this */
X rinfo->MyAddr.Al = 0;
X
X /* NOTE the <= comparison !!! */
X for (c=0; c<=IF_MAX; c++ )
X {
X rinfo->ifdata[c].Line = NOT_USED;
X rinfo->ifdata[c].Technology = NOT_USED;
X rinfo->ifdata[c].Ring = NOT_USED;
X rinfo->ifdata[c].RingPort = NOT_USED;
X rinfo->ifdata[c].Sent = NOT_USED;
X rinfo->ifdata[c].Received = NOT_USED;
X }
X
X rinfo->Idle = 0;
X rinfo->BadCount = 0;
X rinfo->LoopCount = 0;
X rinfo->TTLCount = 0;
X }
X
END_OF_FILE
if test 2513 -ne `wc -c <'IPP/router/TableInit.c'`; then
echo shar: \"'IPP/router/TableInit.c'\" unpacked with wrong size!
fi
# end of 'IPP/router/TableInit.c'
fi
if test -f 'IPP/router/router.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'IPP/router/router.c'\"
else
echo shar: Extracting \"'IPP/router/router.c'\" \(2629 characters\)
sed "s/^X//" >'IPP/router/router.c' <<'END_OF_FILE'
X/* -----------------------------------------------------------------------------------
X * Ident: router.c
X * Author: Damiano Bolla 1993
X * All this project is covered by the GNU Copyright.
X */
X
X#include <stdio.h>
X#include <unistd.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include "defs.h"
X#include "debug.h"
X#include "packet.h"
X#include "router.h"
X#include "func_defs.h"
X
Xstruct Debug dbg;
X
X/* This is the main file of a routing machine.
X * What a routing machine has to do is set itself up using the comand line
X * Cycle in a loop that read a packet for each interface that is UP
X * Them act on the packet.
X */
X
Xint main (char *argv[], int argc)
X {
X struct Routing rinfo;
X
X int error; /* For the select.. */
X struct timeval timeout;
X
X int c;
X
X /* Oh, well, here I am ... I have to setup the damm machine.///.. */
X /* First thing to do is to setup dhe debug system... no ? */
X if ( DebugInit ( "localhost", "1234", "Router") ) exit (1);
X
X /* The we setup the whole systemmm, debug info already go via dbg */
X if ( RouterInit ( &rinfo ) ) exit (1);
X
X /* Ok, I have to close the stdout and stderr fd, NOT stdin (0) */
X fclose (stdout);
X fclose (stderr);
X
X /* Now I must have my own address, I put it into the debug ident field */
X strcpy (dbg.ident, ipp_ntoa(&rinfo.MyAddr));
X
X for (;;)
X {
X FD_ZERO (&rinfo.readfds); /* Reset all bits */
X timeout.tv_sec = IDLE_TOUT; /* Timeout in seconds */
X timeout.tv_usec = 0; /* and no microseconds */
X
X /* We have to set the mask each time we come here... */
X for (c=1; c <=IF_MAX; c++ ) if ( rinfo.ifdata[c].Line )
X FD_SET (rinfo.ifdata[c].Line, &rinfo.readfds);
X
X /* Not only we have to wait for possible packets BUT for rings too */
X for (c=1; c <=IF_MAX; c++ ) if ( rinfo.ifdata[c].Ring )
X FD_SET (rinfo.ifdata[c].Ring, &rinfo.readfds);
X
X error = select (MAX_FILES, &rinfo.readfds, NULL, NULL, &timeout);
X
X /* Done nothing, I got a timeout, let's write it down... */
X if ( error == 0 )
X {
X sprintf (dbg.msg,"router: Being Idle");
X DebugCall ( ERR_MSG, DEBUG_TEXT );
X rinfo.Idle++;
X }
X
X /* Good there is something to do, let's do it */
X if ( error > 0 )
X {
X sprintf (dbg.msg,"router: Calling RouterIo");
X DebugCall ( ERR_MSG, DEBUG_TEXT );
X RouterIo ( &rinfo );
X }
X
X if ( error < 0 )
X {
X sprintf (dbg.msg,"router: Select failed");
X DebugCall ( ERR_SELECT, DEBUG_CRITICAL );
X /* It may be a descriptor gone out, check for it ! */
X }
X
X } /* End of the newerending for loop... */
X
X exit (0);
X }
X
END_OF_FILE
if test 2629 -ne `wc -c <'IPP/router/router.c'`; then
echo shar: \"'IPP/router/router.c'\" unpacked with wrong size!
fi
# end of 'IPP/router/router.c'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 6 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...