DIRECTORY CommBuffer USING [Encapsulation, Overhead], IP USING [Address], NS USING [Host, Net], Process USING [Priority, priorityClient1, priorityClient3], Pup USING [Host, Net]; Driver: CEDAR DEFINITIONS = { BYTE: TYPE = [0..100H); Encapsulation: TYPE = CommBuffer.Encapsulation; Type: TYPE = {none, ethernet, ethernetOne, phone, imp, spare, spare1, spare2}; SendProc: TYPE = PROC [network: Network, buffer: Buffer, bytes: NAT]; RecvProc: TYPE = PROC [network: Network, buffer: Buffer, bytes: NAT] RETURNS [Buffer]; Network: TYPE = REF NetworkObject; NetworkObject: TYPE = RECORD [ next: Network, ip: RECORD [ host: IP.Address, getEncapsulation: PROC [Network, IP.Address] RETURNS [Encapsulation], send: SendProc, return: SendProc, recv: RecvProc, sendTranslate: SendProc, recvTranslate: RecvProc, translation: REF ANY ], ns: RECORD [ net: NS.Net, getEncapsulation: PROC [Network, NS.Host] RETURNS [Encapsulation], send: SendProc, return: SendProc, recv: RecvProc, sendTranslate: SendProc, recvTranslate: RecvProc, translation: REF ANY ], pup: RECORD [ net: Pup.Net, host: Pup.Host, getEncapsulation: PROC [Network, Pup.Host] RETURNS [Encapsulation], send: SendProc, return: SendProc, recv: RecvProc, sendTranslate: SendProc, recvTranslate: RecvProc, translation: REF ANY ], other: RECORD [ netHostOther: REF ANY, getEncapsulation: PROC [Network, REF ANY] RETURNS [Encapsulation], send: SendProc, return: SendProc, recv: RecvProc, sendTranslate: SendProc, recvTranslate: RecvProc, translation: REF ANY ], raw: RECORD [ send: SendProc ], error: RECORD [ recv: PROC [network: Network, buffer: Buffer, bytes: NAT] RETURNS [Buffer] ], setPromiscuous: PROC [network: Network, promiscuous: BOOL], isThisForMe: PROC [network: Network, buffer: Buffer] RETURNS [yes: BOOL], toBroadcast: PROC [network: Network, buffer: Buffer] RETURNS [yes: BOOL], moreBuffers: PROC [network: Network, total: NAT], interceptor: Interceptor, stats: REF ANY, instanceData: REF ANY, type: Type, speed: INT, -- Bits per second index: CARDINAL, -- first is 1 (for forwarder) hearSelf: BOOL, recvSick: BOOL, sendSick: BOOL, dead: BOOL ]; GetNetworkChain: PROC RETURNS [Network]; GetNumberOfNetworks: PROC RETURNS [CARDINAL]; AddNetwork: PROC [Network]; NoThankYou: PROC [Network, Buffer, NAT] RETURNS [Buffer]; SendType: TYPE = { ip, ipReturn, ipTranslate, ns, nsReturn, nsTranslate, pup, pupReturn, pupTranslate, other, otherReturn, otherTranslate, raw }; RecvType: TYPE = { ip, ipTranslate, ns, nsTranslate, pup, pupTranslate, other, otherTranslate, error }; InsertReceiveProc: PROC [network: Network, type: RecvType, proc: RecvProc]; AllocBuffer: PROC RETURNS [Buffer]; FreeBuffer: PROC [Buffer]; dataBytesInBuffer: NAT = 1500; bytesInDriverTail: NAT = 10; bytesToRead: NAT = dataBytesInBuffer+bytesInDriverTail; wordsInIocb: NAT = 12; Buffer: TYPE = REF BufferObject; BufferObject: TYPE = MACHINE DEPENDENT RECORD [ ovh: CommBuffer.Overhead, data: PACKED ARRAY [0..dataBytesInBuffer) OF BYTE, driverTail: PACKED ARRAY [0..bytesInDriverTail) OF BYTE ]; recvPriority: Process.Priority = Process.priorityClient3; sendPriority: Process.Priority = Process.priorityClient3; watcherPriority: Process.Priority = Process.priorityClient1; -- normal Interceptor: TYPE = REF InterceptorRep; InterceptorRep: TYPE; SendInterceptor: TYPE = PROC [ send: SendType, data: REF ANY, network: Network, buffer: Buffer, bytes: NAT] RETURNS [kill: BOOL _ FALSE]; RecvInterceptor: TYPE = PROC [ recv: RecvType, data: REF ANY, network: Network, buffer: Buffer, bytes: NAT] RETURNS [kill: BOOL _ FALSE]; CreateInterceptor: PROC [ network: Network, sendMask: PACKED ARRAY SendType OF BOOL, sendProc: SendInterceptor, recvMask: PACKED ARRAY RecvType OF BOOL, recvProc: RecvInterceptor, data: REF ANY, promiscuous: BOOL] RETURNS [Interceptor]; DestroyInterceptor: PROC [Interceptor]; }. ®Driver.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Hal Murray, May 9, 1986 4:18:43 am PDT Driver management Protocol Binding network = NIL => whole chain and future additions Buffer management Buffers are VM.Pinned and have IOCBs permanently assigned. They should only be created by DriverImpl. Do not NEW your own. This breaks the compilation dependency between protocols. Each protocol must make sure their buffers fit into the space allocated in a Driver.BufferObject. Drivers must add on their encapsulation. The run time TYPE of a buffer (actually the buffer object) gets smashed as the buffer is handed back and forth between the drivers and the protocol modules. As you probably guessed, smashing TYPEs is not for the faint hearted. This is necessary in order for the correct Finalization routine to get notified. (It also bypasses a Debugger bug.) The rules are that the RC maps must be identical and all the package reference counts must be the same. In our case, all the REFs are inside the Overhead and the package use count is always 0. Priority Disk runs at priorityClient2 = priorityForeground Intercepting, Spying, Lightning... A client is expected to inspect the buffer promptly and not change anything. Multiple clients are supported. They each see all packets requested by their mask. If any client kills a packet, it is not passed through to the normal system routine. The system automatically filters out trash that promiscuous mode drags in, so clients don't need to kill that. NB: This interface assumes that all official protocols are already hooked in. Things will get confused if anybody (else) smashes any of the procs in a NetworkObject while an any interceptor is active. That could be fixed by adding an interface to store into those procs. It would store into the saved copy rather than the NetworkObject if any interceptor is active. There may be a few late calls to the client's sendProc or recvProc. ʱ˜codešœ ™ Kšœ Ïmœ1™