DIRECTORY Basics USING [Byte], BufferDefs USING [PupBuffer], Commander USING [ CommandProc, Register ], DriverDefs USING [Network, PutOnGlobalInputQueue], EthernetOneDriver, EthernetOneFace USING [DeviceHandle, HostArray, InputHost, InputHosts, MulticastCapabilities, nullDeviceHandle], ExplicitExport USING [ ExportExplicitly ], IO, LupineRuntime USING [ BindingError ], Multicast, MulticastRpcControl, MulticastRpcServerImpl, PrincOpsUtils USING [GlobalFrame], PupRouterDefs USING [DontForwardPupBuffer, GetRoutingTableEntry, maxHop, RoutingTableEntry, SetPupForwarder], PupTypes USING [allHosts, PupHostID, PupNetID], RPC USING [ Conversation, EncryptionKey, ExportFailed, matchAllVersions, unencrypted ], RPCPrivate USING [GetRPCPackets], VoiceUtils USING [ CmdOrToken, CurrentPasskey, OwnNetAddress, Problem, ReportFR ] ; MulticastImpl: CEDAR PROGRAM IMPORTS Commander, DriverDefs, EthernetOneFace, ExplicitExport, IO, LupineRuntime, MulticastRpcControl, MulticastRpcServerImpl, PrincOpsUtils, PupRouterDefs, RPC, RPCPrivate, VoiceUtils EXPORTS Multicast SHARES EthernetOneDriver, MulticastRpcServerImpl = { ourNet: PupTypes.PupNetID; ourHost: PupTypes.PupHostID; multicastOK: BOOL _ FALSE; etherDevice: EthernetOneFace.DeviceHandle _ EthernetOneFace.nullDeviceHandle; oldEnqueueRecvd: UNSAFE PROC [BufferDefs.PupBuffer] RETURNS [BOOLEAN] _ NIL; map: PACKED ARRAY Basics.Byte OF PupTypes.PupHostID _ ALL[PupTypes.allHosts]; hostArray: EthernetOneFace.HostArray _ ALL[FALSE]; TurnOnMulticastForNet: PUBLIC PROC [shh: RPC.Conversation, net: PupTypes.PupNetID] RETURNS [ok: BOOL] = TRUSTED { device: EthernetOneFace.DeviceHandle; network: DriverDefs.Network; him: POINTER TO FRAME[EthernetOneDriver]; rte: PupRouterDefs.RoutingTableEntry _ PupRouterDefs.GetRoutingTableEntry[net]; IF multicastOK THEN RETURN[TRUE]; IF rte = NIL THEN RETURN[FALSE]; network _ rte.network; IF network = NIL THEN RETURN[FALSE]; IF network.device # ethernetOne THEN RETURN[FALSE]; him _ LOOPHOLE[PrincOpsUtils.GlobalFrame[LOOPHOLE[network.sendBuffer]]]; device _ him.ether; oldEnqueueRecvd _ him.EnqueueRecvd; IF NOT EthernetOneFace.MulticastCapabilities[device].canDo THEN RETURN[FALSE]; IF EthernetOneFace.MulticastCapabilities[device].multicastsEnabled THEN RETURN[FALSE]; ourNet _ net; ourHost _ [LOOPHOLE[network.hostNumber]]; hostArray _ ALL[FALSE]; hostArray[PupTypes.allHosts] _ TRUE; hostArray[ourHost] _ TRUE; map _ ALL[PupTypes.allHosts]; etherDevice _ device; EthernetOneFace.InputHosts[etherDevice, @hostArray]; multicastOK _ TRUE; PupRouterDefs.SetPupForwarder[MyForwarder]; RPCPrivate.GetRPCPackets[MyEnqueueRecvd]; RETURN[TRUE]; }; TurnOffMulticast: PUBLIC PROC[shh: RPC.Conversation] = TRUSTED { EthernetOneFace.InputHost[etherDevice, ourHost]; PupRouterDefs.SetPupForwarder[PupRouterDefs.DontForwardPupBuffer]; RPCPrivate.GetRPCPackets[oldEnqueueRecvd]; oldEnqueueRecvd _ NIL; multicastOK _ FALSE; }; HandleMulticast: PUBLIC PROC [shh: RPC.Conversation, net: PupTypes.PupNetID, realHost, listeningTo: PupTypes.PupHostID] RETURNS [ok: BOOL] = TRUSTED { IF multicastOK AND net = ourNet AND realHost # PupTypes.allHosts AND realHost # ourHost THEN { IF map[realHost] # PupTypes.allHosts THEN RETURN[FALSE]; IF hostArray[listeningTo] THEN RETURN[FALSE]; -- prevent loops! hostArray[realHost] _ TRUE; map[realHost] _ listeningTo; EthernetOneFace.InputHosts[etherDevice, @hostArray]; RETURN[TRUE]; }; RETURN[FALSE]; }; StopHandlingMulticast: PUBLIC PROC [ shh: RPC.Conversation, realHost: PupTypes.PupHostID] = TRUSTED { IF multicastOK AND realHost # PupTypes.allHosts AND realHost # ourHost THEN { map[realHost] _ PupTypes.allHosts; hostArray[realHost] _ FALSE; EthernetOneFace.InputHosts[etherDevice, @hostArray]; }; }; numForwarded: CARDINAL_0; -- can wrap numConsidered: CARDINAL_0; MyForwarder: UNSAFE PROC [b: BufferDefs.PupBuffer] = UNCHECKED { n: PupTypes.PupNetID _ b.dest.net; rte: PupRouterDefs.RoutingTableEntry _ PupRouterDefs.GetRoutingTableEntry[n]; network: DriverDefs.Network; listeningTo: PupTypes.PupHostID _ map[b.dest.host]; numConsidered _ numConsidered+1; IF n # ourNet OR rte = NIL OR rte.hop > PupRouterDefs.maxHop OR (network _ rte.network) = NIL OR hostArray[listeningTo] THEN { PupRouterDefs.DontForwardPupBuffer[b]; RETURN; }; numForwarded _ numForwarded+1; network.encapsulatePup[b, listeningTo]; network.sendBuffer[b]; }; MyEnqueueRecvd: UNSAFE PROC [b: BufferDefs.PupBuffer] RETURNS [BOOLEAN] = UNCHECKED { IF oldEnqueueRecvd # NIL AND oldEnqueueRecvd[b] THEN RETURN[TRUE]; DriverDefs.PutOnGlobalInputQueue[b]; RETURN[TRUE]; }; serverInterfaceName: MulticastRpcControl.InterfaceName; serverPassword: RPC.EncryptionKey; MulticastInit: Commander.CommandProc = { ENABLE RPC.ExportFailed => { VoiceUtils.Problem["Multicast export failed", $System]; GOTO Failed; }; serverInterfaceName _ [ type: "Multicast.Lark", instance: VoiceUtils.CmdOrToken[cmd: cmd, key: "MulticastInstance", default: "Michaelson.Lark"]]; serverPassword _ VoiceUtils.CurrentPasskey[VoiceUtils.CmdOrToken[ cmd: cmd, key: "MulticastPassword", default: "MFLFLX"]]; MulticastRpcControl.UnexportInterface[]; MulticastRpcControl.ExportInterface[ interfaceName: serverInterfaceName, user: serverInterfaceName.instance, password: serverPassword]; ExplicitExport.ExportExplicitly["Multicast.Lark", serverInterfaceName.instance, RPC.matchAllVersions, MulticastRpcControl.LupineProtocolVersion, MulticastRpcServerImpl.ServerDispatcher]; VoiceUtils.ReportFR["Export[Multicast.Lark, %s]", $System, NIL, IO.rope[serverInterfaceName.instance]]; IF ~TurnOnMulticastForNet[RPC.unencrypted, VoiceUtils.OwnNetAddress[].net] THEN { VoiceUtils.Problem["Multicast enabling failed", $System]; GOTO Failed; }; EXITS Failed => MulticastRpcControl.UnexportInterface[!LupineRuntime.BindingError=>CONTINUE]; }; Commander.Register["Multicast", MulticastInit, "Multicast > -- Initialize and Export Multicast"]; }. Stewart, July 18, 1983 5:12 pm, fixes for RPC Packets Stewart, December 22, 1983 3:51 pm, Cedar 5 Swinehart, November 25, 1985 11:45:46 am PST, RPC Access!, Swinehart xMulticastImpl.mesa L. Stewart December 22, 1983 3:56 pm Last Edited by: Swinehart, December 3, 1985 3:01:34 pm PST Stolen from PupRouterOut.PupRouterSendThis driver encapsulate and send it Swinehart, November 25, 1985 11:45:02 am PST Add Multicast command: "Multicast Michaelson.Lark MFFLX" is default. changes to: DIRECTORY, IMPORTS, SHARES, MulticastInit, Commander Κ˜J™J™$J™:šΟk ˜ Jšœœ˜Jšœ œ ˜Jšœ œ˜*Jšœ œ"˜2Jšœ˜Jšœœ[˜pJšœœ˜*Jšœ˜Jšœœ˜%J˜ J˜J˜Jšœœ˜"JšœœZ˜mJšœ œ!˜/JšœœN˜WJšœ œ˜!JšœQ˜QJ˜—J˜Jšœ ˜Jšœ7œw˜ΉJšœ ˜Jšœ.˜4J˜Jšœ˜Jšœ˜Jšœ œœ˜J˜MJš œ œœœœ˜LJ˜Jš œœœ œœ˜MJšœ'œœ˜2J˜šΟnœœœœ'œœœ˜qJ˜%J˜Jšœœœœ˜)J˜OJšœ œœœ˜!Jš œœœœœ˜ Jšœ˜Jš œ œœœœ˜$Jšœœœœ˜3Jšœœœ˜HJ˜Jšœ#˜#Jš œœ5œœœ˜NJšœAœœœ˜VJšœ ˜ Jšœ œ˜)Jšœ œœ˜Jšœœ˜$Jšœœ˜Jšœœ˜J˜Jšœ4˜4Jšœœ˜Jšœ+˜+Jšœ)˜)Jšœœ˜ J˜—J˜š žœœœœœ˜@Jšœ0˜0JšœB˜BJšœ*˜*Jšœœ˜Jšœœ˜J˜—J˜šžœœœœ˜4JšœCœœœ˜aš œ œœœœ˜^Jšœ#œœœ˜8Jš œœœœΟc˜@Jšœœ˜Jšœ˜Jšœ4˜4Jšœœ˜ J˜—Jšœœ˜J˜—J˜šžœœœ˜$Jšœœ/œ˜@šœ œœœ˜MJšœ"˜"Jšœœ˜Jšœ4˜4J˜—J˜—J˜Jšœœ˜%Jšœœ˜J˜šž œœœ œ˜@J™*J˜"J˜MJ˜J˜3Jšœ ˜ šœ œœœ œœœœ˜~Jšœ&˜&Jšœ˜J˜—J™J˜Jšœ'˜'J˜J˜—J˜š žœœœœœ œ˜UJš œœœœœœ˜BJšœ$˜$Jšœœ˜ J˜—J˜Jšœ7˜7Jšœœ˜"J˜šž œ˜(š˜JšœKœ ˜]—šœ˜J˜Jšœa˜a—šœA˜AJšœ8˜8—Jšœ(˜(šœ$˜$Jšœ#˜#Jšœ#˜#J˜—JšœPœg˜ΊJšœ;œœ%˜gšœœ4˜QJšœ9˜9Jšœ˜ J˜—š˜JšœMœ˜W—J˜—J˜šœ.˜.Jšœ^˜^—J˜Jšœ˜Jšœ*œ˜5Jšœ+˜+Jšœ9Οr ˜DJ˜code™,K™DKšœ  4™@—K™—…—Ϊl