internal static byte[] Request (TFTP.OpCodes OpCode, string RemoteFileName, TFTP.Modes Mode, int BlockSize, long TransferSize, int Timeout) { // Request packet structure // ----------------------------------------------------------------------------- // |OpCode|FileName|0|Mode|0|BlkSize|0|BSVal|0|TSize|0|TSVal|0|Timeout|0|TVal|0| // ----------------------------------------------------------------------------- int len; string packetStr = ""; string mode = Mode.ToString().ToLower(); string blockSize = BlockSize.ToString(); string nullChar = "\0"; byte[] packet; // Create packet as a string switch (OpCode) { case TFTP.OpCodes.RRQ: packetStr = nullChar + (char)1; break; case TFTP.OpCodes.WRQ: packetStr = nullChar + (char)2; break; } packetStr += RemoteFileName + nullChar + mode + nullChar + "blksize" + nullChar + BlockSize.ToString() + nullChar + "tsize" + nullChar + TransferSize.ToString() + nullChar + "timeout" + nullChar + Timeout.ToString() + nullChar; len = packetStr.Length; packet = new byte[len]; // Encode packet as ASCII bytes packet = System.Text.Encoding.ASCII.GetBytes(packetStr); return(packet); }
internal static TFTP.OpCodes OpCode(byte[] ReceivedData) { TFTP.OpCodes opCode = new TFTP.OpCodes(); switch (ReceivedData[1]) { case 3: opCode = TFTP.OpCodes.DATA; break; case 4: opCode = TFTP.OpCodes.ACK; break; case 5: opCode = TFTP.OpCodes.ERROR; break; case 6: opCode = TFTP.OpCodes.OACK; break; } return(opCode); }
// Get implementation internal static bool Get (string LocalFilename, string RemoteFilename, string Host, TFTP.Modes Mode, int BlockSize, int Timeout) { int recvLen, remoteFileSize = 0, buffer = BlockSize + 4; long bytesReceived = 0; BinaryWriter BWriter = new BinaryWriter(File.Open(LocalFilename, FileMode.Create)); TFTP.OpCodes opCode = new TFTP.OpCodes(); IPHostEntry hInfo = Dns.GetHostEntry(Host); IPAddress address = hInfo.AddressList[0]; IPEndPoint remoteEP = new IPEndPoint(address, 69); EndPoint localEP = (remoteEP); Socket UDPSock = new Socket (remoteEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp); // Create initial request and buffer for response byte[] sendData = TFTPPacket.Create.Request (TFTP.OpCodes.RRQ, RemoteFilename, Mode, BlockSize, 0, Timeout); byte[] recvData = new byte[BlockSize + 4]; UDPSock.ReceiveTimeout = Timeout * 1000; // Send request and wait for response UDPSock.SendTo(sendData, remoteEP); recvLen = UDPSock.ReceiveFrom(recvData, ref localEP); // Get TID remoteEP.Port = ((IPEndPoint)localEP).Port; // Fire connected event TFTP.FireOnConnect(); while (true) { // Read opcode opCode = TFTPPacket.Read.OpCode(recvData); // DATA packet if (opCode == TFTP.OpCodes.DATA) { bytesReceived += recvLen - 4; // Fire OnTransfer Event and pass along bytesReceived TFTP.FireOnTransfer(bytesReceived, remoteFileSize); for (int h = 4; h < recvLen; h++) { BWriter.Write(recvData[h]); } sendData = TFTPPacket.Create.Ack(recvData[2], recvData[3]); // Check if this packet is the last if (recvLen < buffer) { // Send final ACK UDPSock.SendTo(sendData, remoteEP); // Fire OnTransferFinish Event TFTP.FireOnTransferFinish(); break; } } // OACK packet else if (opCode == TFTP.OpCodes.OACK) { remoteFileSize = TFTPPacket.Read.TSize(recvData); sendData = TFTPPacket.Create.Ack(0, 0); } // ERROR packet else if (opCode == TFTP.OpCodes.ERROR) { TFTPPacket.Read.Error transferError = new TFTPPacket.Read.Error(recvData); TFTP.FireOnTransferError (transferError.Code, transferError.Message); break; } // Send next packet UDPSock.SendTo(sendData, remoteEP); recvLen = UDPSock.ReceiveFrom(recvData, ref localEP); remoteEP.Port = ((IPEndPoint)localEP).Port; } BWriter.Close(); UDPSock.Close(); // Fire OnDisconnect Event TFTP.FireOnDisconnect(); return true; }
// Put implementation internal static bool Put (string LocalFilename, string RemoteFilename, string Host, TFTP.Modes Mode, int BlockSize, int Timeout) { int[] block = new int[2]; int bufferSize = BlockSize; long fileSize, bytesSent = 0; BinaryReader BReader = new BinaryReader(File.Open(LocalFilename, FileMode.Open)); FileInfo sendFile = new FileInfo(LocalFilename); TFTP.OpCodes opCode = new TFTP.OpCodes(); IPHostEntry hostInfo = Dns.GetHostEntry(Host); IPAddress address = hostInfo.AddressList[0]; IPEndPoint remoteEP = new IPEndPoint(address, 69); EndPoint localEP = (remoteEP); Socket UDPSock = new Socket (remoteEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp); // Retrieve filesize for tsize option fileSize = sendFile.Length; // Create initial request and buffer for response byte[] sendData = TFTPPacket.Create.Request (TFTP.OpCodes.WRQ, RemoteFilename, Mode, BlockSize, fileSize, Timeout); byte[] recvData = new byte[bufferSize]; UDPSock.ReceiveTimeout = Timeout * 1000; // Send request and wait for response UDPSock.SendTo(sendData, remoteEP); UDPSock.ReceiveFrom(recvData, ref localEP); //Get TID remoteEP.Port = ((IPEndPoint)localEP).Port; // Fire OnConnect Event TFTP.FireOnConnect(); while (true) { // Read opcode opCode = TFTPPacket.Read.OpCode(recvData); // ACK packet if (opCode == TFTP.OpCodes.ACK) { block = TFTPPacket.Modify.IncrementBock(recvData, block); sendData = BReader.ReadBytes(bufferSize); bytesSent += sendData.Length; // Fire OnTransfer Event TFTP.FireOnTransfer(bytesSent, fileSize); sendData = TFTPPacket.Create.Data(sendData, block[0], block[1]); // Check if this packet is the last if (sendData.Length < bufferSize + 4) { // Send final data packet and wait for ack while (true) { UDPSock.SendTo(sendData, remoteEP); UDPSock.ReceiveFrom(recvData, ref localEP); remoteEP.Port = ((IPEndPoint)localEP).Port; // Check the blocks and break free if equal if (TFTPPacket.Read.CheckBlock(sendData, recvData)) { break; } } // Fire OnTransferFinish Event TFTP.FireOnTransferFinish(); break; } } // OACK packet else if (opCode == TFTP.OpCodes.OACK) { sendData = BReader.ReadBytes(bufferSize); sendData = TFTPPacket.Create.Data(sendData, 0, 1); bytesSent += sendData.Length - 4; // Fire OnTransfer Event TFTP.FireOnTransfer(bytesSent, fileSize); if (fileSize == 0) { // Fire OnTransferFinish Event TFTP.FireOnTransferFinish(); break; } else { // Check if this packet is the last if (sendData.Length < bufferSize + 4) { // Send final data packet and wait for ack while (true) { UDPSock.SendTo(sendData, remoteEP); UDPSock.ReceiveFrom(recvData, ref localEP); remoteEP.Port = ((IPEndPoint)localEP).Port; // Check the blocks and break free if equal if (TFTPPacket.Read.CheckBlock(sendData, recvData)) { break; } } // Fire OnTransferFinish Event TFTP.FireOnTransferFinish(); break; } } } else if (opCode == TFTP.OpCodes.ERROR) { TFTPPacket.Read.Error transferError = new TFTPPacket.Read.Error(recvData); TFTP.FireOnTransferError (transferError.Code, transferError.Message); break; } // Send next packet UDPSock.SendTo(sendData, remoteEP); UDPSock.ReceiveFrom(recvData, ref localEP); remoteEP.Port = ((IPEndPoint)localEP).Port; } BReader.Close(); UDPSock.Close(); // Fire OnDisconnect Event TFTP.FireOnDisconnect(); return(true); }