www.pudn.com > TFTPUtil_Class_Version_1.3.0.zip > TFTPServer.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using NSpring.Logging;
using NSpring.Logging.Loggers;
namespace TFTPUtil
{
///
/// The TFTPUtil Server Main Listener Class
///
public class TFTPServer
{
#region VARS
private struct ProcessStruct
{
public Thread thread;
public TFTPServerProcess process;
public ThreadStart threadStart;
public ProcessStruct(ref Thread thread_, ref ThreadStart threadStart_, ref TFTPServerProcess process_)
{
thread = thread_;
process = process_;
threadStart = threadStart_;
}
}
private string LoggingMethodOptions = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
private int ResendInterval = 1; //How many seconds before resending
private int Timeout = 10; //How many seconds before counting TID timedout
///
/// Allow RFC 2347 (TFTP Option Extension)
///
public bool AllowOptions = true;
///
/// Specifies if we allow read requests
///
public bool AllowRRQ = true;
///
/// Specifies if we allow write requests
///
public bool AllowWRQ = false;
///
/// Specifies if write requests can overwrite an existing file
///
public bool AllowWRQOverwrite = false;
private int ListenerPort = 69; //The UDP port we should be listening for requests on
private const int MaxRecvSize = 65468; //Maximum receive size in bytes
private bool Loop = false; //Controls if we should be receiving datagrams
///
/// Check for existing TIDs in RRQ and WRQ requests
///
public bool RRQWRQStateCheck = true;
private IPEndPoint myEndpoint; //The IPEndPoint that the server is using
private Socket mySocket; //The socket the server is using
private Timer CheckTimer; //Timer object that goes through active states
private List CurrStates = new List(10); //List to keep track of currently spawned TFTPServerProcess
//private List CurrStates = new List(10);
Logger logger = new WindowsEventLogger(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
private bool ClientMode = false;
private string ClientHost;
private string FullPath = System.IO.Directory.GetCurrentDirectory();
///
/// The TFTP server event handler
///
public event TFTPServerEventHandler TFTPServerEvent;
public event TFTPServerTransferEventHandler TFTPServerTransferEvent;
private readonly object CurrStatesLock = new object();
private Level EventLevel = Level.Info;
private Level LogLevel = Level.Info;
private IPAddress[] BadIPs;
//public delegate void TFTPStateEventHandler(object o, TFTPServerTransferEventArgs e);
public delegate void TFTPServerProcessHandler(object o, TFTPServerProcessEventArgs e);
///
/// A byte array of ASCII characters representing the TFTP error number 1
///
public readonly byte[] Error1 = { 0, 5, 0, 1, 70, 105, 108, 101, 32, 110, 111, 116, 32, 102, 111, 117, 110, 100, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 2
///
public readonly byte[] Error2 = { 0, 5, 0, 2, 65, 99, 99, 101, 115, 115, 32, 118, 105, 111, 108, 97, 116, 105, 111, 110, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 3
///
public readonly byte[] Error3 = { 0, 5, 0, 3, 68, 105, 115, 107, 32, 102, 117, 108, 108, 32, 111, 114, 32, 97, 108, 108, 111, 99, 97, 116, 105, 111, 110, 32, 101, 120, 99, 101, 101, 100, 101, 100, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 4
///
public readonly byte[] Error4 = { 0, 5, 0, 4, 73, 108, 108, 101, 103, 97, 108, 32, 84, 70, 84, 80, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 5
///
public readonly byte[] Error5 = { 0, 5, 0, 5, 85, 110, 107, 110, 111, 119, 110, 32, 116, 114, 97, 110, 115, 102, 101, 114, 32, 73, 68, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 6
///
public readonly byte[] Error6 = { 0, 5, 0, 6, 70, 105, 108, 101, 32, 97, 108, 114, 101, 97, 100, 121, 32, 101, 120, 105, 115, 116, 115, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 7
///
public readonly byte[] Error7 = { 0, 5, 0, 7, 78, 111, 32, 115, 117, 99, 104, 32, 117, 115, 101, 114, 46, 0 };
///
/// A byte array of ASCII characters representing the TFTP error number 8
///
public readonly byte[] Error8 = { 0, 5, 0, 8, 84, 114, 97, 110, 115, 102, 101, 114, 32, 116, 101, 114, 109, 105, 110, 97, 116, 101, 100, 32, 100, 117, 101, 32, 116, 111, 32, 111, 112, 116, 105, 111, 110, 32, 110, 101, 116, 105, 97, 116, 105, 111, 110, 46, 0};
///
/// A byte array of ASCII characters representing the "unknown error"
///
public readonly byte[] ErrorUnknown = { 0, 5, 0, 0, 65, 110, 32, 117, 110, 107, 110, 107, 110, 111, 119, 110, 32, 101, 114, 114, 111, 114, 32, 111, 99, 99, 117, 114, 114, 101, 100, 46, 0 };
Thread testthread;
#endregion
///
/// Creates an instance of the TFTPServer class
///
public TFTPServer()
{
SetIPAddr();
AddMsg(Level.Verbose, myEndpoint.ToString());
}
///
/// Creates an instance of the TFTPServer class
///
/// A string specifying the path the TFTP server should retrieve files from
public TFTPServer(string FilePath)
{
if (System.IO.Directory.Exists(FilePath))
FullPath = FilePath;
SetIPAddr();
AddMsg(Level.Verbose, myEndpoint.ToString());
}
///
/// Creates an instance of the TFTPServer class
///
/// An integer specifying the UDP Port the TFTP server should listen on
public TFTPServer(int UDP_Port)
{
ListenerPort = UDP_Port;
SetIPAddr();
}
///
/// Creates an instance of the TFTPServer class
///
/// An IPAddress specifying the local IP address the TFTP seerver should listen on
public TFTPServer(IPAddress IPAddr)
{
SetIPAddr(IPAddr);
}
///
/// Creates an instance of the TFTPServer class
///
/// An integer specifying the UDP Port the TFTP server should listen on
/// An IPAddress specifying the local IP address the TFTP seerver should listen on
public TFTPServer(int UDP_Port, IPAddress IPAddr)
{
ListenerPort = UDP_Port;
SetIPAddr(IPAddr);
}
///
/// Creates an instance of the TFTPServer class
///
/// An integer specifying the UDP Port the TFTP server should listen on
/// A string specifying the path the TFTP server should retrieve files from
public TFTPServer(int UDP_Port, string FilePath)
{
ListenerPort = UDP_Port;
if (System.IO.Directory.Exists(FilePath))
FullPath = FilePath;
SetIPAddr();
AddMsg(Level.Verbose, myEndpoint.ToString());
}
///
/// Creates an instance of the TFTPServer class
///
/// An integer specifying the UDP Port the TFTP server should listen on
/// An IPAddress specifying the local IP address the TFTP seerver should listen on
/// A string specifying the path the TFTP server should retrieve files from
public TFTPServer(int UDP_Port, IPAddress IPAddr, string FilePath)
{
ListenerPort = UDP_Port;
if (System.IO.Directory.Exists(FilePath))
FullPath = FilePath;
SetIPAddr(IPAddr);
}
///
/// Creates an instance of the TFTPServer class
///
/// An integer specifying the UDP Port the TFTP server should listen on
/// A string specifying the path the TFTP server should retrieve files from
/// The NSpring level to log messages via the specified method
/// The NSpring level to log messages
/// A string representing what access clients have to files
/// If we shoud allow TFTP option extensions from TFTP clients
/// Defines if we should check for TIDs in read and write requests
/// An integer in milliseconds specifying how long before resending the last packet
/// An integer in milliseconds specifying how long before the request is timed out
/// A string specifying the parameters to use with the logging method
/// A string containing IP addresses to block
public TFTPServer(int UDP_Port,
string FilePath,
string LoggingLevel,
string DisplayLevel,
string FileAccess,
bool AllowTFTPOptions,
bool CheckReadWriteState,
int ResendInterval,
int TimeoutInterval,
string[] LoggingMethodInfo,
string IPs)
{
ListenerPortNumber = UDP_Port;
SetIPAddr();
Path = FilePath;
this.LoggingLevel = LoggingLevel;
SendEventLevel = DisplayLevel;
AllowOptions = AllowTFTPOptions;
this.FileAccess(FileAccess);
RRQWRQStateCheck = CheckReadWriteState;
ResendIntervalSeconds = ResendInterval;
TimeoutSeconds = TimeoutInterval;
logger = new WindowsEventLogger(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
LoggingMethod = LoggingMethodInfo;
BlockedIPs = IPs;
}
///
/// Creates an instance of the TFTPServer class
///
/// An integer specifying the UDP Port the TFTP server should listen on
/// A string specifying the path the TFTP server should retrieve files from
/// The NSpring level to log messages via the specified method
/// The NSpring level to log messages
/// A string representing what access clients have to files
/// If we shoud allow TFTP option extensions from TFTP clients
/// Defines if we should check for TIDs in read and write requests
/// An integer in milliseconds specifying how long before resending the last packet
/// An integer in milliseconds specifying how long before the request is timed out
/// A string specifying the parameters to use with the logging method
/// A string containing IP addresses to block
/// An IPAddress specifying the local IP address the TFTP seerver should listen on
public TFTPServer(int UDP_Port,
string FilePath,
string LoggingLevel,
string DisplayLevel,
string FileAccess,
bool AllowTFTPOptions,
bool CheckReadWriteState,
int ResendInterval,
int TimeoutInterval,
string[] LoggingMethodInfo,
string IPs,
IPAddress IPAddr)
{
ListenerPortNumber = UDP_Port;
SetIPAddr(IPAddr);
Path = FilePath;
this.LoggingLevel = LoggingLevel;
SendEventLevel = DisplayLevel;
AllowOptions = AllowTFTPOptions;
this.FileAccess(FileAccess);
RRQWRQStateCheck = CheckReadWriteState;
ResendIntervalSeconds = ResendInterval;
TimeoutSeconds = TimeoutInterval;
logger = new WindowsEventLogger(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
LoggingMethod = LoggingMethodInfo;
BlockedIPs = IPs;
}
///
/// Cleans up everything
///
~TFTPServer()
{
if (CheckTimer != null)
CheckTimer.Dispose();
try
{
if (mySocket != null)
mySocket.Shutdown(SocketShutdown.Receive);
}
catch (ObjectDisposedException ex)
{ }
CurrStates.Clear();
if (logger != null)
logger.Close();
}
///
/// Stops the TFTP server from listening for requests
///
public void StopListener()
{
AddMsg(Level.Verbose, "Stopping Listening...");
Loop = false;
if (CheckTimer != null)
CheckTimer.Dispose();
try
{
if (mySocket != null)
{
mySocket.Shutdown(SocketShutdown.Both); //I think we want both here unlike the process
mySocket.Close();
}
}
catch (ObjectDisposedException ex)
{
AddMsg(Level.Verbose, "Caught socket object disposed exception");
AddMsg(Level.Debug, "Socket exception: " + ex.Message);
}
lock (CurrStatesLock)
{
for (int StateIndex = 0; StateIndex < CurrStates.Count; StateIndex++)
{
//CurrStates[StateIndex].StartListener();
CurrStates[StateIndex].process.StopListener();
CurrStates[StateIndex].process.MyClose();
}
CurrStates.Clear();
}
AddMsg(Level.Info, "Stopped Listening");
logger.Close();
}
///
/// Starts the TFTP server listening for requests
///
public void StartListener()
{
try
{
try
{
logger.Open();
}
catch
{
}
AddMsg(Level.Verbose, "Creating Socket");
mySocket = new Socket(myEndpoint.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
AddMsg(Level.Verbose, "Binding Socket");
mySocket.Bind(myEndpoint);
StartCheckTimer();
Loop = true;
AddMsg(Level.Verbose, "Starting to Listen");
AddMsg(Level.Info, "Listening for requests on IP address " + myEndpoint.Address.ToString() + " port " + myEndpoint.Port.ToString());
StartReceive();
}
catch (SocketException ex)
{
Loop = false;
if (ex.ErrorCode == 10048)
{
AddMsg(Level.Exception, "Unable to start listening on " + myEndpoint.Address.ToString() + " port " + myEndpoint.Port.ToString() + ". There maybe another service listening on that port.");
}
else
{
AddMsg(Level.Verbose, "Handled StartListener socket exception: " + ex.Message);
AddMsg(Level.Debug, "Handled StartListener socket exception at: " + ex.StackTrace);
Loop = false;
}
}
}
private void StartCheckTimer()
{
CheckTimer = new Timer(
new TimerCallback(CheckStates), //Name of the method to call
null, // Don't send a state object
1000, // Start timer in 1 second
1000); // Do callback every 1 second
}
private void CheckStates(object state)
{
AddMsg(Level.Debug, DateTime.Now.ToString() + " Server CheckStates timer callback started...");
lock (CurrStatesLock)
{
if (CurrStates.Count > 0)
{
List RemoveList = new List(CurrStates.Count);
for (int StateIndex = 0; StateIndex < CurrStates.Count; StateIndex++)
{
//if (CurrStates[StateIndex] != null && CurrStates[StateIndex].IsListening)
if (CurrStates[StateIndex].process != null && CurrStates[StateIndex].process.IsListening)
{
//CurrStates[StateIndex].CheckStates();
CurrStates[StateIndex].process.CheckStates();
}
else
{
RemoveList.Add(StateIndex);
}
}
for (int RemoveIndex = 0; RemoveIndex < RemoveList.Count; RemoveIndex++)
{
try
{
AddMsg(Level.Verbose, "Removing state at index " + ((int)RemoveList[RemoveIndex]).ToString());
//ProcessStruct currStruct = CurrStates[RemoveList[RemoveIndex]];
//if (CurrStates[RemoveList[RemoveIndex]] != null && CurrStates[RemoveList[RemoveIndex]].IsListening)
if (CurrStates[RemoveList[RemoveIndex]].process != null)
{
CurrStates[RemoveList[RemoveIndex]].process.MyClose();
}
if (CurrStates[RemoveList[RemoveIndex]].thread != null)
{
CurrStates[RemoveList[RemoveIndex]].thread.Interrupt();
//CurrStates[RemoveList[RemoveIndex]].thread.Abort();
}
CurrStates[RemoveList[RemoveIndex]].threadStart = null;
CurrStates[RemoveList[RemoveIndex]].process =null ;
CurrStates[RemoveList[RemoveIndex]].thread = null;
CurrStates.RemoveAt(RemoveList[RemoveIndex]);
AddMsg(Level.Debug, "CheckStates Count after " + CurrStates.Count.ToString());
}
catch
{
AddMsg(Level.Verbose, "An error occurred while trying to remove a state");
}
}
}
}
AddMsg(Level.Debug, "...Server CheckStates timer callback finished " + DateTime.Now.ToString());
}
private void StartReceive()
{
while (Loop)
{
bool ReceivedWorked = false;
//Setup maximum bytes to receive
Byte[] ReceivedBytes = new Byte[MaxRecvSize];
//Create an EndPoint that will connect to any IP and any port
EndPoint tempPoint = new IPEndPoint(IPAddress.Any, 0);
AddMsg(Level.Verbose, "Waiting for datagram...");
int NumBytesReceived = 0;
try
{
NumBytesReceived = mySocket.ReceiveFrom(ReceivedBytes, ref tempPoint);
ReceivedWorked = true;
}
catch (Exception ex)
{
if (Loop)
{
AddMsg(Level.Info, "An error occurred while trying receive a packet");
AddMsg(Level.Verbose, "Handled receive packet exception: " + ex.Message);
AddMsg(Level.Debug, "Handled receive packet exception at: " + ex.StackTrace);
}
}
if (ReceivedWorked)
{
IPEndPoint RemoteEndPoint = (IPEndPoint)tempPoint;
AddMsg(Level.Verbose, "Received datagram from " + ((IPEndPoint)RemoteEndPoint).Address.ToString() + ":" + ((IPEndPoint)RemoteEndPoint).Port.ToString());
bool FoundMatch = true;
if (ClientMode)
{
AddMsg(Level.Debug, "Entered ClientMode");
FoundMatch = false;
bool IsIP = false;
IPAddress HostAddr;
IsIP = IPAddress.TryParse(ClientHost, out HostAddr);
if ((HostAddr != null) && IsIP)
{
if (RemoteEndPoint.Address.Equals(HostAddr))
FoundMatch = true;
}
if (IsIP == false)
{
foreach (IPAddress ip in Dns.GetHostAddresses(ClientHost))
{
if (RemoteEndPoint.Address.Equals(ip))
FoundMatch = true;
}
}
}
bool FoundBadIPMatch = false;
if (BadIPs.Length > 0)
{
AddMsg(Level.Debug, "Checking to see if IP is in list of bad IPs");
foreach (IPAddress addr in BadIPs)
{
if (RemoteEndPoint.Address.Equals(addr))
FoundBadIPMatch = true;
}
AddMsg(Level.Debug, "Finished bad IP check");
}
if (FoundMatch)
{
if (FoundBadIPMatch == false)
{
ProcessDatagram(ReceivedBytes, NumBytesReceived, RemoteEndPoint);
}
else
{
AddMsg(Level.Info, "Blocking TFTP request from " + RemoteEndPoint.Address.ToString());
}
}
}
}
}
private void ProcessDatagram(byte[] ReceivedBytes, int NumBytesReceived, IPEndPoint RemoteEndPoint)
{
int CurrOpcode = Convert.ToInt16(ReceivedBytes[1]);
string EndPointString = ((IPEndPoint)RemoteEndPoint).Address.ToString() + ":" + ((IPEndPoint)RemoteEndPoint).Port.ToString();
AddMsg(Level.Verbose, "Found Opcode " + CurrOpcode.ToString() + " from " + EndPointString);
if ((CurrOpcode == 1) || (CurrOpcode == 2))
{
TFTPServerProcessContainer container = new TFTPServerProcessContainer();
container.process = new TFTPServerProcess(FullPath,
LogLevel,
EventLevel,
AllowRRQ,
AllowWRQ,
AllowWRQOverwrite,
AllowOptions,
RRQWRQStateCheck,
ResendInterval,
Timeout,
logger,
myEndpoint.Address);
container.threadStart = new ThreadStart(container.process.StartListener);
container.thread = new Thread(container.threadStart);
container.thread.Name = "TFTP Server Process Thread: " + container.process.ident.ToString();
container.thread.IsBackground = true;
container.thread.Start();
lock (CurrStatesLock)
{
//CurrStates.Add(tftpproc);
CurrStates.Add(container);
}
for (int SleepCounter = 0; SleepCounter <= 5; SleepCounter++)
{
if (container.process.IsListening)
{
container.process.ProcessDatagram(ReceivedBytes, NumBytesReceived, RemoteEndPoint);
OnTFTPServerTransferEvent(new TFTPServerTransferEventArgs(container.process));
container.process.TFTPServerProcessEvent += new TFTPServerProcessEventHandler(this.TFTPProcessEventListener);
SleepCounter = 10;
}
else
{
//Wait a little bit for the thread to start listening
Thread.Sleep(100);
}
}
}
else
{
AddMsg(Level.Verbose, "Sending error4 generated in default case " + EndPointString);
Send(RemoteEndPoint, Error4);
}
}
///
///
///
///
///
public void TFTPProcessEventListener(object sender, TFTPServerProcessEventArgs e)
{
AddMsg(e.EventLevel, e.EventString);
}
private void Send(IPEndPoint RemoteEndPoint, byte[] Data)
{
try
{
mySocket.BeginSendTo(Data, 0, Data.Length, SocketFlags.None, RemoteEndPoint, new AsyncCallback(SendCallback), mySocket);
}
catch (Exception ex)
{
AddMsg(Level.Info, "A problem occurred while trying to send a packet to " + RemoteEndPoint.Address.ToString() + ":" + RemoteEndPoint.Port.ToString());
AddMsg(Level.Verbose, "Handled exception in send : " + ex.Message);
AddMsg(Level.Debug, "Handled RRQ file exception: " + ex.StackTrace);
}
}
private void SendUnknownError(IPEndPoint RemoteEndPoint)
{
Send(RemoteEndPoint, ErrorUnknown);
}
private void SendCallback(IAsyncResult result)
{
//Socket s = (Socket)result.AsyncState;
//int send = s.EndSendTo(result);
((Socket)result.AsyncState).EndSendTo(result);
}
///
///
///
/// A string representing the DNS hostname or IP address to retrieve the file from
/// The port the Host TFTP server is listening o n
/// The filename to request from the Host
/// Indicates if we should request the file size
///
///
public void GetFile(string Host, int Port, string Filename, bool Filesize, int Timeout, int TransferSize)
{
TFTPServerProcessContainer container = new TFTPServerProcessContainer();
container.process = new TFTPServerProcess(FullPath,
LogLevel,
EventLevel,
AllowRRQ,
AllowWRQ,
AllowWRQOverwrite,
AllowOptions,
RRQWRQStateCheck,
ResendInterval,
Timeout,
logger,
myEndpoint.Address);
OnTFTPServerTransferEvent(new TFTPServerTransferEventArgs(container.process));
container.process.TFTPServerProcessEvent += new TFTPServerProcessEventHandler(this.TFTPProcessEventListener);
ClientMode = true;
ClientHost = Host;
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse(Host), Port);
container.threadStart = new ThreadStart(container.process.StartListener);
container.thread = new Thread(container.threadStart);
container.thread.Name = "TFTP Server Process Thread";
container.thread.IsBackground = true;
container.thread.Start();
lock (CurrStatesLock)
{
//CurrStates.Add(tftpproc);
CurrStates.Add(container);
}
for (int SleepCounter = 0; SleepCounter <= 5; SleepCounter++)
{
if (container.process.IsListening)
{
container.process.GetFile(Host, Port, Filename, Filesize, Timeout, TransferSize);
SleepCounter = 10;
StartCheckTimer();
}
else
{
//Wait a little bit for the thread to start listening
Thread.Sleep(100);
}
}
}
///
///
///
/// A string representing the DNS hostname or IP address of the TFTP server to put the file on
/// The port the Host TFTP server is listening o n
/// The filename to put on the specified Host
/// Indicates if we should send the file size
///
///
public void PutFile(string Host, int Port, string Filename, bool Filesize, int Timeout, int TransferSize)
{
TFTPServerProcessContainer container = new TFTPServerProcessContainer();
TFTPServerProcess tftpproc = new TFTPServerProcess(FullPath,
LogLevel,
EventLevel,
AllowRRQ,
AllowWRQ,
AllowWRQOverwrite,
AllowOptions,
RRQWRQStateCheck,
ResendInterval,
Timeout,
logger,
myEndpoint.Address);
OnTFTPServerTransferEvent(new TFTPServerTransferEventArgs(tftpproc));
tftpproc.TFTPServerProcessEvent += new TFTPServerProcessEventHandler(this.TFTPProcessEventListener);
ClientMode = true;
ClientHost = Host;
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse(Host), Port);
container.threadStart = new ThreadStart(container.process.StartListener);
container.thread = new Thread(container.threadStart);
container.thread.Name = "TFTP Server Process Thread";
container.thread.IsBackground = true;
container.thread.Start();
lock (CurrStatesLock)
{
//CurrStates.Add(tftpproc);
CurrStates.Add(container);
}
for (int SleepCounter = 0; SleepCounter <= 5; SleepCounter++)
{
if (container.process.IsListening)
{
container.process.PutFile(Host, Port, Filename, Filesize, Timeout, TransferSize);
SleepCounter = 10;
StartCheckTimer();
}
else
{
//Wait a little bit for the thread to start listening
Thread.Sleep(100);
}
}
}
private void OnTFTPServerEvent(TFTPServerEventArgs e)
{
if (TFTPServerEvent != null)
TFTPServerEvent(null, e);
}
private void OnTFTPServerTransferEvent(TFTPServerTransferEventArgs e)
{
if (TFTPServerTransferEvent != null)
TFTPServerTransferEvent(null, e);
}
private void AddMsg(Level level, string text)
{
if (level >= EventLevel)
OnTFTPServerEvent(new TFTPServerEventArgs(text));
if (logger.IsOpen && (level >= LogLevel))
logger.Log(level, text);
}
private void SetIPAddr()
{
try
{
IPHostEntry localMachineInfo = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ipAddr in localMachineInfo.AddressList)
{
//Find the first IPv4 address
if (ipAddr.AddressFamily == AddressFamily.InterNetwork)
{
myEndpoint = new IPEndPoint(ipAddr, ListenerPort);
}
}
}
catch (SocketException)
{
myEndpoint = new IPEndPoint(IPAddress.Any, ListenerPort);
}
AddMsg(Level.Verbose, myEndpoint.ToString());
}
private void SetIPAddr(IPAddress IPAddr)
{
try
{
if (IPAddress.Any == IPAddr)
{
myEndpoint = new IPEndPoint(IPAddress.Any, ListenerPort);
}
else
{
IPHostEntry localMachineInfo = Dns.GetHostEntry(Dns.GetHostName());
bool IPMatch = false;
for (int i = 0; i < localMachineInfo.AddressList.Length; i++)
{
if (localMachineInfo.AddressList[i].Equals(IPAddr))
{
IPMatch = true;
myEndpoint = new IPEndPoint(localMachineInfo.AddressList[i], ListenerPort);
AddMsg(Level.Debug, "SetIPAddr found match and setting to " + localMachineInfo.AddressList[i].ToString());
}
}
if (!IPMatch)
myEndpoint = new IPEndPoint(localMachineInfo.AddressList[0], ListenerPort);
}
}
catch (SocketException)
{
myEndpoint = new IPEndPoint(IPAddress.Any, ListenerPort);
}
AddMsg(Level.Verbose, myEndpoint.ToString());
}
///
/// Gets whether we are listening for TFTP requests
///
public bool IsListening
{
get
{
return Loop;
}
}
///
/// Gets or sets the Path where to retrieve or put files
///
public string Path
{
get
{
return FullPath;
}
set
{
if (System.IO.Directory.Exists(value))
FullPath = value;
}
}
///
/// Gets or sets the NSpring level indicating whent to send events
///
public string SendEventLevel
{
get
{
return EventLevel.ToString();
}
set
{
switch (value)
{
case "Debug":
EventLevel = Level.Debug;
break;
case "Verbose":
EventLevel = Level.Verbose;
break;
case "Config":
EventLevel = Level.Config;
break;
case "Info":
EventLevel = Level.Info;
break;
case "Warning":
EventLevel = Level.Warning;
break;
case "Exception":
EventLevel = Level.Exception;
break;
}
}
}
///
/// Gets or sets the NSpring logging level
///
public string LoggingLevel
{
get
{
return LogLevel.ToString();
}
set
{
switch (value)
{
case "Debug":
logger.Level = Level.Debug;
LogLevel = Level.Debug;
break;
case "Verbose":
logger.Level = Level.Verbose;
LogLevel = Level.Verbose;
break;
case "Config":
logger.Level = Level.Config;
LogLevel = Level.Config;
break;
case "Info":
logger.Level = Level.Info;
LogLevel = Level.Info;
break;
case "Warning":
logger.Level = Level.Warning;
LogLevel = Level.Warning;
break;
case "Exception":
logger.Level = Level.Exception;
LogLevel = Level.Exception;
break;
}
}
}
///
/// Gets or sets the listener IP addresses
///
public IPAddress[] ListenerIPAddresses
{
get
{
//Currently we only listen on one IP but we want to listen on more
if (myEndpoint != null)
{
IPAddress[] list = new IPAddress[] { myEndpoint.Address };
return list;
}
else
{
return new IPAddress[] { };
}
}
set
{
if (!IsListening)
SetIPAddr(value[0]);
//myEndpoint = new IPEndPoint(value[0], ListenerPort);
}
}
///
/// Gets or sets the port to listen to TFTP requests on
///
public int ListenerPortNumber
{
get
{
return myEndpoint.Port;
}
set
{
if (!IsListening)
SetIPAddr();
//myEndpoint = new IPEndPoint(ListenerIPAddresses[0], value);
}
}
///
/// Gets the current number of active sessions
///
public int NumberSessions
{
get
{
return CurrStates.Count;
}
}
private void FileAccess(string access)
{
switch (access)
{
case "No Access":
AllowRRQ = false;
AllowWRQ = false;
AllowWRQOverwrite = false;
break;
case "Read Only":
AllowRRQ = true;
AllowWRQ = false;
AllowWRQOverwrite = false;
break;
case "Write":
AllowRRQ = false;
AllowWRQ = true;
AllowWRQOverwrite = false;
break;
case "Read and Write":
AllowRRQ = true;
AllowWRQ = true;
AllowWRQOverwrite = false;
break;
case "Read and Overwrite":
AllowRRQ = true;
AllowWRQ = true;
AllowWRQOverwrite = true;
break;
}
}
///
/// Gets or sets an integer in seconds specifying the interval before resending the last packet
///
public int ResendIntervalSeconds
{
get
{
return ResendInterval;
}
set
{
if ((value >= 1) && (value <= 255))
ResendInterval = value;
}
}
///
/// Gets or set an integer in seconds specifying how longer before the connection is considered to be timed out
///
public int TimeoutSeconds
{
get
{
return Timeout;
}
set
{
if ((value >= 1) && (value <= 255))
Timeout = value;
}
}
///
/// Gets or sets the logging method and parameters
///
public string[] LoggingMethod
{
get
{
return new string[] { logger.GetType().ToString(), LoggingMethodOptions };
}
set
{
try
{
if (value.Length == 2)
{
AddMsg(Level.Debug, "Changing logger to " + value[0] + " with options " + value[1]);
if (logger.IsOpen)
logger.Close();
switch (value[0].ToLower())
{
case "windows event":
logger = new WindowsEventLogger(value[1]);
break;
case "sql":
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(value[1]);
logger = new DatabaseLogger(conn, "INSERT INTO [" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + " Log] ([EventDatetime], [EventLevel], [EventMessage]) VALUES ('{ts}', '{ln}', '{msg}')");
logger.EventFormatter = new NSpring.Logging.EventFormatters.PatternEventFormatter("{ts} {msg}");
break;
case "text file":
if (logger.GetType().ToString() != "NSpring.Logging.Loggers.FileLogger")
logger = new FileLogger(value[1]);
break;
case "xml file":
if (logger.GetType().ToString() != "NSpring.Logging.Loggers.StreamLogger")
{
System.IO.FileStream LoggerStream = new System.IO.FileStream(value[1], System.IO.FileMode.Append);
logger = new StreamLogger(LoggerStream);
}
break;
case "email":
string[] emailparams = value[1].Split(',');
if (emailparams.Length == 3)
logger = new EmailLogger(emailparams[0], emailparams[1], emailparams[2]);
break;
default:
logger.Open();
AddMsg(Level.Debug, "Someone tried changing the logger to some type we don't know: " + value[0]);
break;
}
if (!logger.IsOpen)
logger.Open();
LoggingMethodOptions = value[1];
}
else
{
AddMsg(Level.Debug, "Someone tried changing the logger and had " + value.Length.ToString() + " items in the array so we didn't do anything.");
}
}
catch (Exception ex)
{
AddMsg(Level.Info, "An error occurred while trying to change the logging method");
AddMsg(Level.Verbose, "Handled exception: " + ex.Message);
AddMsg(Level.Debug, "Handled exception at: " + ex.StackTrace);
}
}
}
public string BlockedIPs
{
get
{
string tempips = "";
if (BadIPs != null)
{
for (int i = 0; i < BadIPs.Length; i++)
{
if (BadIPs[i] != null)
{
tempips += BadIPs[i].ToString();
if (i != (BadIPs.Length - 1))
tempips += ";";
}
}
}
return tempips;
}
set
{
int i = 0;
string[] tempips = value.Split(';');
IPAddress[] tempIPAddrs = new IPAddress[tempips.Length];
foreach (string ip in tempips)
{
IPAddress tempaddr;
if (IPAddress.TryParse(ip, out tempaddr))
{
tempIPAddrs[i] = tempaddr;
i++;
}
}
BadIPs = tempIPAddrs;
}
}
}
}