153 lines
4.7 KiB
Plaintext
153 lines
4.7 KiB
Plaintext
Unit NwRIP;
|
|
|
|
{ NwTP Version 0.6, Copyright 1993,1994 R. Spronk
|
|
|
|
WARNING: Test your program thoroughly if you're using nwRip functions.
|
|
----------------------------------------------------------------------
|
|
|
|
Using the RIP functionality the wrong way may very well result in
|
|
aborting servers ! (no kidding.)
|
|
|
|
As far as I know the diagnostic RIP function(s) included in this unit
|
|
are perfectly safe to use.
|
|
|
|
Based on:
|
|
|
|
-GETALL, written in C by Barry Lagerweij of 2:2802/110.2
|
|
posted in the Fido NOVELL area on Tue 7 Sep 93 0:36.
|
|
-GETRIP, written in C by Koos van den Hout of 2:500/101.11012
|
|
last updated 8 Feb 93 }
|
|
|
|
INTERFACE
|
|
|
|
Uses nwMisc,nwIPX;
|
|
|
|
CONST ECB_COUNT=10;
|
|
{ assumption : 10 receiveECBs are used, which means a max of 500 networks }
|
|
|
|
{ Type definitions for RIP request/response structures}
|
|
type TRIPentry=record
|
|
network:TnetworkAddress;
|
|
hops :word;
|
|
ticks :word;
|
|
end;
|
|
|
|
TRIPanswerPacket=record
|
|
operation:word;
|
|
entry :array[1..50] of TRIPEntry;
|
|
end;
|
|
|
|
TRIPinfo=array[1..50*ECB_COUNT] of record
|
|
address:TnetworkAddress;
|
|
hops :byte;
|
|
Ticks :word;
|
|
end;
|
|
|
|
Function GetAllNetworks(SegmentNetworkAddress:TnetworkAddress;
|
|
Var NetInfo:TRIPinfo):word;
|
|
{SegmentNetworkAddress: The target network whose routers
|
|
will be queried. Set to all zeroes (00 00 00 00)
|
|
if querying your own segment.
|
|
NetInfo : the buffer where the network-info is stored.
|
|
Returns : the number of known networks.
|
|
|
|
Assumed is that IPXInitialize is already called. }
|
|
|
|
IMPLEMENTATION {===========================================================}
|
|
|
|
Function GetAllNetworks(SegmentNetworkAddress:TnetworkAddress;
|
|
Var NetInfo:TRIPinfo):word;
|
|
Var
|
|
RIPrequest :TRIPanswerPacket;
|
|
RIPanswer :array[1..ECB_COUNT] of TRIPanswerPacket;
|
|
RequestEcb :Tecb;
|
|
RequestIPXheader:TipxHeader;
|
|
ReplyECB :array[1..ECB_COUNT] of Tecb;
|
|
ReplyIPX :array[1..ECB_COUNT] of TipxHeader;
|
|
Target :TinternetworkAddress;
|
|
Sourcesocket :word;
|
|
RIPsocket :word;
|
|
|
|
NumberOfNets :word;
|
|
cnt :word;
|
|
n :word;
|
|
RoutableNetworks:word;
|
|
timer1,timer2:word;
|
|
|
|
Begin
|
|
RIPsocket:=$0453;
|
|
|
|
SourceSocket:=0;
|
|
{ open socket for receiving the RIP packets }
|
|
IF NOT IPXopenSocket(SourceSocket,SHORT_LIVED_SOCKET)
|
|
then begin
|
|
result:=nwIPX.result;
|
|
GetAllnetworks:=0;
|
|
exit;
|
|
end;
|
|
|
|
{set-up sendpacket }
|
|
target.net:=SegMentNetworkAddress;
|
|
fillchar(target.node,6,#$FF); { all nodes i.e. all routers }
|
|
target.socket:=RIPsocket;
|
|
IPXsetUpSendECB(NIL,SourceSocket,target,@RIPrequest,SizeOf(RIPrequest),
|
|
RequestIPXheader, RequestECB);
|
|
RequestIPXheader.packetType := 1;
|
|
{ 1=RIP / Any value will work/ type seems to be ignored by Routers
|
|
as long as socket is OK. }
|
|
|
|
{ set-up the RIP request }
|
|
FillChar(RIPrequest,SizeOf(RIPrequest),#$FF);
|
|
RIPrequest.operation := $0100; { hi-lo, RIP request }
|
|
FillChar(RIPanswer,SizeOf(RIPanswer),#$00);
|
|
|
|
|
|
{ set-up the receive ECBs }
|
|
for n:=1 to ECB_COUNT
|
|
do begin
|
|
IPXsetupListenECB(NIL,SourceSocket,
|
|
@RIPanswer[n],SizeOf(TRIPanswerPacket),
|
|
ReplyIpx[n],ReplyECB[n]);
|
|
IPXListenForPacket(ReplyECB[n]);
|
|
end;
|
|
|
|
{ send the RIP request }
|
|
IPXSendPacket(RequestECB);
|
|
|
|
{ wait a while for answers }
|
|
IPXgetIntervalMarker(timer1);
|
|
REPEAT
|
|
IPXrelinquishcontrol;
|
|
IPXGetIntervalMarker(timer2);
|
|
UNTIL abs(timer2-timer1)>20;
|
|
|
|
NumberOfNets := 0;
|
|
|
|
{ check all possible RIP responses, and fill the tables }
|
|
for n:=1 to ECB_COUNT
|
|
do if (ReplyECB[n].INuseFlag=0) and (RIPanswer[n].operation=$0200)
|
|
then begin
|
|
RoutableNetworks:=(swap(ReplyIPX[n].Length)-32) DIV SizeOf(TRIPentry);
|
|
for cnt:=1 to RoutableNetworks
|
|
do begin
|
|
inc(NumberOfNets);
|
|
With NetInfo[NumberOfNets]
|
|
do begin
|
|
Address:=RIPanswer[n].entry[cnt].network;
|
|
hops:=swap(RIPanswer[n].entry[cnt].hops);
|
|
ticks:=swap(RIPanswer[n].Entry[cnt].ticks);
|
|
end;
|
|
end;
|
|
end
|
|
else IPXcancelEvent(ReplyECB[n]);
|
|
|
|
{ our socket is no longer needed }
|
|
IPXCloseSocket(SourceSocket);
|
|
|
|
{ return the number of networks we found }
|
|
GetAllNetworks:=NumberOfNets;
|
|
end;
|
|
|
|
|
|
end.
|