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.