J
jgbid
Hi, I'm trying to build an IP Scanner inc c# for a specific port (80)
and for specific IP Ranges.
For example 24.36.148.1 to 24.36.148.255
My first step was to use TcpClient, but there are nothing to control
Timeout Connection... and I wasn't interested to wait 25-30sec for each
ip.
After some search, it's look like Socket was the solution with
BeginConnect. After a first look, I thought that all worked perfectly,
but after a second look... I noticed that after some scan... approx. 10
or 15, nothing work...
If I set maximum thread to 1, it works, this it what I got:
24.36.148.10--->Close
24.36.148.23--->Close
24.36.148.24--->Close
24.36.148.28--->Close
24.36.148.66--->Close
24.36.148.70--->Close
24.36.148.77--->Close
24.36.148.116--->Close
24.36.148.121--->Close
24.36.148.126--->Close
24.36.148.130--->Close
24.36.148.132--->Close
24.36.148.137--->Close
24.36.148.146--->Close
24.36.148.147--->Close
24.36.148.148--->Close
24.36.148.154--->Close
24.36.148.164--->Close
24.36.148.177--->Close
24.36.148.180--->Open
24.36.148.197--->Close
24.36.148.199--->Close
24.36.148.202--->Close
24.36.148.213--->Close
24.36.148.216--->Close
24.36.148.234--->Close
24.36.148.241--->Close
24.36.148.251--->Close
where the only one with Port 80 open is "24.36.148.180--->Open"
and where "Close" means "the remote host is reachable, but refuses
connections on a port"
If I set maximum Thread to 5 or something else better... the only thing
I got is :
24.36.148.10--->Close
Nothing else..... like if Socket doesn't work when they are too many
socket open...
But I tried by anything I know to kill the bad sockets
Here is my code :
PortScanner Class :
Main Code :
StartHTTPScanning -> is called by a Form Button
and for specific IP Ranges.
For example 24.36.148.1 to 24.36.148.255
My first step was to use TcpClient, but there are nothing to control
Timeout Connection... and I wasn't interested to wait 25-30sec for each
ip.
After some search, it's look like Socket was the solution with
BeginConnect. After a first look, I thought that all worked perfectly,
but after a second look... I noticed that after some scan... approx. 10
or 15, nothing work...
If I set maximum thread to 1, it works, this it what I got:
24.36.148.10--->Close
24.36.148.23--->Close
24.36.148.24--->Close
24.36.148.28--->Close
24.36.148.66--->Close
24.36.148.70--->Close
24.36.148.77--->Close
24.36.148.116--->Close
24.36.148.121--->Close
24.36.148.126--->Close
24.36.148.130--->Close
24.36.148.132--->Close
24.36.148.137--->Close
24.36.148.146--->Close
24.36.148.147--->Close
24.36.148.148--->Close
24.36.148.154--->Close
24.36.148.164--->Close
24.36.148.177--->Close
24.36.148.180--->Open
24.36.148.197--->Close
24.36.148.199--->Close
24.36.148.202--->Close
24.36.148.213--->Close
24.36.148.216--->Close
24.36.148.234--->Close
24.36.148.241--->Close
24.36.148.251--->Close
where the only one with Port 80 open is "24.36.148.180--->Open"
and where "Close" means "the remote host is reachable, but refuses
connections on a port"
If I set maximum Thread to 5 or something else better... the only thing
I got is :
24.36.148.10--->Close
Nothing else..... like if Socket doesn't work when they are too many
socket open...
But I tried by anything I know to kill the bad sockets
Here is my code :
PortScanner Class :
Code:
public class PortScanner
{
private int m_iPort = 0;
private bool m_bTimeOut = false;
private string m_sStatus = "Not connected";
private IPAddress m_oIPAddress;
private AutoResetEvent m_oARSConnectDone = new AutoResetEvent(false);
public PortScanner(long iIP)
{
m_oIPAddress = new IPAddress(iIP);
m_iPort = 80;
}
public int Port
{
get{ return m_iPort; }
}
public string IP
{
get{ return m_oIPAddress.ToString(); }
}
private void ConnectCallback(IAsyncResult ar)
{
if(m_bTimeOut)
return;
Socket oSocket = (Socket)ar.AsyncState;
try
{
// Complete the connection.
oSocket.EndConnect(ar);
m_sStatus = "Open";
}
catch
{
// The EndConnect method will throw a SocetException if the remote
// host is reachable, but refuses connections on a port.
m_sStatus = "Close";
}
finally
{
if (oSocket.Connected)
oSocket.Shutdown(SocketShutdown.Both);
oSocket.Close();
oSocket=null;
m_oARSConnectDone.Set(); //tell the main thread that the callback
has been finished.
Console.WriteLine(m_oIPAddress.ToString() + "--->" + m_sStatus);
}
}
// initiate a connection to the port.
public void Scan()
{
try
{
m_bTimeOut = false;
Socket oScanningIpPort = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
oScanningIpPort.BeginConnect(new IPEndPoint(m_oIPAddress, m_iPort),
new AsyncCallback(ConnectCallback), oScanningIpPort);
if(!m_oARSConnectDone.WaitOne(10000, true))
{
m_bTimeOut = true;
oScanningIpPort.Close();
oScanningIpPort = null;
}
m_oARSConnectDone.Close();
}
catch(SocketException ex)
{
Console.WriteLine(ex.ErrorCode);
}
}
}
StartHTTPScanning -> is called by a Form Button
Code:
private Thread m_oThreadScanning;
private Queue m_queueIP = new Queue();
//flag to be used to tell the HTTP Scan Thread that IP is still
enqueuing
private bool m_bEnqueuingIP;
private int m_iMaxRunning = 10;
// private int m_iMaxRunning = 255;
// flag to be used to stop all running threads when user request to
stop
bool m_bRunning = true;
private void EnqueuingIP()
{
m_bEnqueuingIP = true;
XmlDocument xDocLstIPs = new XmlDocument();
xDocLstIPs.Load("IPRange.xml");
XmlNodeList xLstNdIPs = xDocLstIPs.SelectNodes("/RangeIPs/RangeIP");
foreach(XmlElement xElemDomain in xLstNdIPs)
{
try
{
Int64 iStartIP =
long.Parse(xElemDomain.GetAttribute("start").ToString());
Int64 iEndIP =
long.Parse(xElemDomain.GetAttribute("end").ToString());
while(iStartIP <= iEndIP)
{
m_queueIP.Enqueue(iStartIP);
iStartIP++;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
Thread.Sleep(2000);
}
//end enqueuing
m_bEnqueuingIP = false;
}
public void HTTPScanRunFunction()
{
while(m_bRunning && (m_queueIP.Count > 0 || m_bEnqueuingIP) &&
int.Parse(Thread.CurrentThread.Name) < m_iMaxRunning)
{
if(m_queueIP.Count == 0 && m_bEnqueuingIP)
{
Thread.Sleep(500);
continue;
}
long iIP = 0;
lock(m_queueIP)
{
iIP = Convert.ToInt64(m_queueIP.Dequeue());
}
if(iIP == 0)
continue;
PortScanner oPortScanner = new PortScanner(iIP);
// update thread information in the threads view list
ListViewItem itemLog;
itemLog =
listViewThreads.Items[int.Parse(Thread.CurrentThread.Name)];
itemLog.SubItems[0].Text = oPortScanner.IP.ToString();
itemLog.SubItems[1].Text = oPortScanner.Port.ToString();
itemLog.ImageIndex = 1;
itemLog.BackColor = Color.WhiteSmoke;
// initialize status to Connect
itemLog.SubItems[2].Text = "Scanning";
itemLog.ForeColor = Color.Green;
oPortScanner.Scan();
if(m_bRunning == false)
itemLog.SubItems[2].Text = "Stop";
itemLog.ImageIndex = 0;
itemLog.SubItems[0].Text = "";
itemLog.SubItems[1].Text = "";
itemLog.SubItems[2].Text = "";
oPortScanner = null;
}
}
private void HTTPScanning()
{
// start parsing thread
Thread oThreadEnqueuingIP = new Thread(new ThreadStart(EnqueuingIP));
oThreadEnqueuingIP.Name = "ThreadEnqueuingIP";
oThreadEnqueuingIP.Start();
// create the threads
Thread[] threadsRun = new Thread[ m_iMaxRunning ];
int nIndex = 0;
for(nIndex = 0; nIndex < m_iMaxRunning; nIndex ++)
{
// check if thread not created or not suspended
if(threadsRun[nIndex] == null || threadsRun[nIndex].ThreadState !=
ThreadState.Suspended)
{
threadsRun[nIndex] = new Thread( new ThreadStart(
HTTPScanRunFunction ) );
// set thread name equal to its index
threadsRun[nIndex].Name = nIndex.ToString();
lock(listViewThreads)
{
// add a new line in the view for the new thread
ListViewItem item =
listViewThreads.Items.Add(threadsRun[nIndex].Name, 0);
string[] subItems = { "", "", "" };
item.SubItems.AddRange(subItems);
}
Thread.Sleep(200);
// start the thread
threadsRun[nIndex].Start();
}
// check if the thread is suspended
else if(threadsRun[nIndex].ThreadState == ThreadState.Suspended)
{
// resume the thread
threadsRun[nIndex].Resume();
}
}
// wait for all of them to finish
for ( nIndex = 0; nIndex < threadsRun.Length; nIndex ++ )
threadsRun[nIndex].Join();
this.toolBarButtonContinue.Enabled = true;
this.toolBarButtonPause.Enabled = false;
}
private void StartHTTPScanning()
{
// start parsing thread
m_oThreadScanning = new Thread(new ThreadStart(HTTPScanning));
m_oThreadScanning.Start();
}