예제 #1
0
        private void SendMicrocodeResponse(PUP p)
        {
            //
            // The request PUP contains the file number in the lower-order 16-bits of the pup ID.
            // Assuming the number is a valid bootfile, we start sending it to the client's port via EFTP.
            //
            ushort fileNumber = (ushort)p.ID;

            Log.Write(LogType.Verbose, LogComponent.MiscServices, "Microcode request is for file {0}.", fileNumber);

            FileStream microcodeFile = BootServer.GetStreamForNumber(fileNumber);

            if (microcodeFile == null)
            {
                Log.Write(LogType.Warning, LogComponent.MiscServices, "Microcode file {0} does not exist or could not be opened.", fileNumber);
            }
            else
            {
                // Send the file.  The MicrocodeReply protocol is extremely simple:
                // Just send a sequence of MicrocodeReply PUPs containing the microcode data,
                // there are no acks or flow control of any kind.
                Log.Write(LogType.Warning, LogComponent.MiscServices, "Sending microcode file {0}.", fileNumber);
                SendMicrocodeFile(p.SourcePort, microcodeFile);
            }
        }
예제 #2
0
        private void SendBootDirectory(PUP p)
        {
            //
            // From etherboot.bravo
            // "Pup ID: if it is in reply to a BootDirRequest, the ID should match the request.
            // Pup Contents: 1 or more blocks of the following format: A boot file number (the number that goes in the low 16 bits of a
            // BootFileRequest Pup), an Alto format date (2 words), a boot file name in BCPL string format."
            //
            MemoryStream ms = new MemoryStream(PUP.MAX_PUP_SIZE);

            List <BootFileEntry> bootFiles = BootServer.EnumerateBootFiles();

            foreach (BootFileEntry entry in bootFiles)
            {
                BootDirectoryBlock block;
                block.FileNumber = entry.BootNumber;
                block.FileDate   = 0;
                block.FileName   = new BCPLString(entry.Filename);

                byte[] serialized = Serializer.Serialize(block);

                //
                // If this block fits into the current PUP, add it to the stream, otherwise send off the current PUP
                // and start a new one.
                //
                if (serialized.Length + ms.Length <= PUP.MAX_PUP_SIZE)
                {
                    ms.Write(serialized, 0, serialized.Length);
                }
                else
                {
                    PUPPort localPort    = new PUPPort(DirectoryServices.Instance.LocalHostAddress, p.DestinationPort.Socket);
                    PUP     bootDirReply = new PUP(PupType.BootDirectoryReply, p.ID, p.SourcePort, localPort, ms.ToArray());
                    Router.Instance.SendPup(bootDirReply);

                    ms.Seek(0, SeekOrigin.Begin);
                    ms.SetLength(0);
                }
            }

            // Shuffle out any remaining data.
            if (ms.Length > 0)
            {
                PUPPort localPort    = new PUPPort(DirectoryServices.Instance.LocalHostAddress, p.DestinationPort.Socket);
                PUP     bootDirReply = new PUP(PupType.BootDirectoryReply, p.ID, p.SourcePort, localPort, ms.ToArray());
                Router.Instance.SendPup(bootDirReply);
            }
        }
예제 #3
0
        private void SendBootFile(PUP p)
        {
            //
            // The request PUP contains the file number in the lower-order 16-bits of the pup ID.
            // Assuming the number is a valid bootfile, we start sending it to the client's port via EFTP.
            //
            ushort fileNumber = (ushort)p.ID;

            Log.Write(LogType.Verbose, LogComponent.MiscServices, "Boot file request is for file {0}.", fileNumber);

            FileStream bootFile = BootServer.GetStreamForNumber(fileNumber);

            if (bootFile == null)
            {
                Log.Write(LogType.Warning, LogComponent.MiscServices, "Boot file {0} does not exist or could not be opened.", fileNumber);
            }
            else
            {
                // Send the file.
                EFTPManager.SendFile(p.SourcePort, bootFile);
            }
        }