Click here to Skip to main content
Click here to Skip to main content

Network Sniffer and Connection Analyzer

By , 30 Jan 2005
 

Sample Image - HSSniffer.jpg

Introduction

Project is an implementation of a Packet Sniffer that captures packet in a LAN environment using Microsoft .NET environment and written in C#.

Our goal was to build a network utility tool that can be an assistant to programmers, network managers, and private users. Our Sniffer can be useful for monitoring traffic, debugging, fault analysis, network protocol analysis, network intrusion detection, traffic measuring etc.

In order to reach our goals, project supplies some useful features that can be easily used. Features can be summarized like this:

  • Organize captured packets in a connection-oriented view.
  • Smart real-time analyzer enables on-the-fly content viewing while capturing and analyzing.
  • Parse and decode an variety of network protocol.
  • Protocol definition tool to extend protocols that are decodable.
  • Powerful filter provides a flexible mechanism to capture specific packets.
  • Port Scanner utility.
  • Finds process that uses each connection.
  • Syntax highlighting for application data.

We did not use any capture library; instead we wrote our own capture library and build a GUI that serve user an easy interface. To build capture library we used .NET network classes that provide interface to native Winsock API and asynchronous sockets that brings thread based solution to socket programming.

Project Files (Sniffer)

Consts.cs

Class “consts” contain some functions returning string equivalents of protocol field values.

DataManager.cs

Class “DataManager” holds IP datagrams in hash data collection. In order to provide uniqueness it produces a key to every packet and supply adding removing functions that operate on its hash table.

DnsTable.cs

We need to resolve domain names of Ips and this process requires too much time and cause a performance bottlenecks. We overwhelm this problem with building this class that stores resolved domain names in a hash table and serve a function GetName function that first look up IP in its table to resolve its domain name. If this domain name of Ip could not be resolved then request it from a domain name server.

FilterManager.cs

Supply filtering functionality. FilterManager has a container that contains filter items and adding removing functions that allow adding removing filters to its filter container. Most important function FilterManager supplied is isAllowed. This function determines whether packet is to be discarded.

HeaderParser.cs

This supply a helper class that extract field values from Ip Datagram.

IcmpPacket.cs

Define a class that used to set fields of an ICMP packet or extract these fields’ values from IP datagram.

Icmp packets do not have a fixed format. First four bytes are same for all types of Icmp packets, so decoding these packets has some difficulties. We overwhelmed this problem by after decoding type and code values, extract other fields according to these fields. CheckNextFields function is doing that.

getBytes function produces a raw byte array that is put in a form that is ready to send though socket.

There is no need to mention to other functions.

IPv4Datagram.cs

IPv4Datagram class extracts all fields of an Ip datagram. If fragmented, store fragments and when all fragments reach, build the original packet. In addition, class includes functions to handle TCP, UDP, ICMP packets.

Protocols.cs

Protocols class is a static class that stores protocol definitions in a container. First time when this class is accessed, it reads all protocol definition from XML files.

This class contains functions supplied operations to read parse XML data.

ProtocolTemplate.cs

This class extracts fields of a packet according to protocol definitions that are loaded from XML files.

First, we obtain what type of template packet will be build by looking up to Ip datagrams next header section and loads its definition from Protocols class and set its fields by using SetFields function that ProtocolTemplate class provides us.

SnifferException.cs

Contain exception class that will be thrown when a problem arises during sniffing.

SnifferSocket.cs

This file contains core class that builds our Packet Sniffer. It brings an event driven solution to sniffing. We explain it important functions below.

Sniff: creates a socket and binds it to the ip that is supplied, setup socket to receive all packets, begin capturing packets asynchronously.

SetupSocket: put socket in receiving all packets mode.

ReceivePacket: It is called whenever asynchronous Soket.BeginReceive operation is completed and calls itself to keep on receiving packets.

HandleIPv4Datagram: called from ReceivePacket if captured packet is an IPv4 datagram and fires create an IPv4Datagram and fire IPv4DatagramReceived events.

SocketPair.cs

Class that contains a socket handle and a buffer that belongs to this socket.

TcpPacket.cs

Class that decodes fields of an incoming TCP Packet.

trio.cs

This is a helper class used to group Source IP, Destination IP, Source Port, Destination Port, Protocol Number and its string counterpart into a class. We use it to pass all these values in a single structure.

UdpPacket.cs

Class that decodes fields of an incoming UDP Packet.

Project Files (SnifferUI)

AddIP.cs

Class that holds Ip addresses in a container. We use update Ip address list that is being listening.

AddProtocols.cs

This class serve as an interface to add new protocols to Sniffer’s protocol list.

AddressInput.cs

This class is used to get an IP from user.

CheckerForm.cs

This form is a common interface used by ping, trace route and connection checker. Result of the operation reported is to the user in this form.

CheckTool.cs

This is a static class and has functions that are Ping, Trace Route and Check. These functions are called from CheckerForm class’s on load function and given to a thread to not to block other operations.

Ping and TraceRoute operate like original ping and Tracert network utilities but Check is a bit different, first trace path to the remote host and if it can not obtain any response from it, scans a few ports of it that are likely to be in listening state. Such a way it tries to determine if that host entry is alive.

FilterCreater.cs

This class creates filter and adds it to Sniffer’s FilterManager.

Filtering.cs

This class contains functions that used to manage Sniffer’s FilterManager. Here some functions are supplied to add, remove filters and change the order of filters.

Icmp.cs

This is a limited version of ICMP that is used by CheckTool.cs.

icmpView.cs

This is a class that extends the System.Windows.Form.UserControl class. When HandleIcmpPacket is function fired, it is added to the Packet View.

NetStat.cs

This class interfaces the IpHlpApidotnet.IPHelper class. We did not implement IpHlpApidotnet.IPHelper, we only use it and transfer the results of it to list view.

IpHlpApidotnet.IPHelper is a wrapper class that uses IpHlpApi.dll and gets tables of inbound and outbound network connections, including the information on open TCP and UDP ports, IP address, and connection states. What makes it different from other NetStat utilities is the ability to map open ports to the owning application.

OtherProtocols.cs

This is a user control class that uses ProtocolTemplate class and handles dynamically added protocols in user interface.

Setting.cs

This is the static class that holds the settings of tool that are Ping, Trace Route and Connection Checker. These settings related to the protocol type of the outgoing packets that send by mentioned tools.

Settings.cs

This class provides the interface to let user to change settings.

SnifferUI.cs

This class is the core of the interface.

tablesForProc.cs

This class provides two functions that are getProcessId and getProcessName. Using these two functions we relate connection to its owning process.

tcpView.cs

This is a class that extends the System.Windows.Form.UserControl class. When HandleTcpPacket function is fired, it is added to the Packet View.

treeViewFuncs.cs

This class enables viewing decoded packets in tree view. Another feature that provided is, highlighting text in Hexadecimal and Binary Views when user selects a field in tree view.

udpView.cs

This is a class that extends the System.Windows.Form.UserControl class. When HandlUdpPacket function fired, it is added to the Packet View.

Project Files (PortScanner)

Configuration.cs

Parses and extracts configuration data from XML file. This configuration includes the following.

Which servers with which port will be scanned, mail server that will be used, sender of the mails, receiver that will be notified, loop count for scan process and time interval between scans.

CreateFileForm.cs

Creates an interface that ease making XML files configurations.

Logging.cs

This class enables creation of event log and writing of log.

LogItemView.cs

This class enables view of ListViewItems in detail.

PortScanner.cs

This is the core class that scans ports, enables user to control port scanner.

Setting.cs

Saves and loads PortScanner’s settings from XML file. Setting has the file name whose default configuration to be loaded.

SettingForm.cs

This file enables setting configuration file.

Smtp.cs

SMTP class has functions that enable sending mail.

Utility.cs

Provides two functions that are getFileLastModifiedTime and isFileExist.

Here is the our implementation of asynchronous functions.

public void Sniff(String ip) 
{
IP=ip;
Socket socket = new Socket(AddressFamily.InterNetwork,
 SocketType.Raw,ProtocolType.IP);
byte[] buffer = new byte[2048];
SocketPair socketpair = new SocketPair(socket,buffer);
socket.Blocking = true;
try
{
   socket.Bind(new IPEndPoint(IPAddress.Parse(ip),0));
}
catch(SocketException e)
{
   throw new SnifferException("Cannot assign requested address.The 
requested address is not valid in its context.",e);
}
this.SetupSocket(socket);
           
if ( SocketMap_.Contains(ip) ) 
{ 
   throw new SnifferException("Socket already bound on that IP");
} 
else 
{ 
   SocketMap_.Add(ip,socketpair);
}
try 
{           socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,new 
AsyncCallback(this.ReceivePacket),socketpair);
   paused=false;
} 
catch ( Exception e ) 
{ 
   throw new SnifferException("Could not start the Receive",e);
}
}
// Callback function for the Asynchronous Receive on a Socket.
private void ReceivePacket(IAsyncResult ar) 
{
bool fired=false;
int len = 0;
SocketPair p = ar.AsyncState as SocketPair;
Socket socket = p.IPSocket;
int type = 0;
try 
{ 
   len = socket.EndReceive(ar);
} 
catch ( SocketException e) 
{ 
   fired = true;
   FireSnifferError(new SnifferException("Error Receiving 
Packet",e));
}
if (!fired)
{
   type = HeaderParser.ToInt(p.Buffer,0,4);
   try 
   { 
        switch(type) 
    { 
          case 4:
           HandleIPv4Datagram(p.Buffer);
           break;
    }
   } 
   catch ( Exception e ) 
   {
    FireSnifferError(new
SnifferException(e.Message.ToString(),e));
   }
}
if (!this.paused)
{
  socket.BeginReceive(p.Buffer,0,p.Buffer.Length,SocketFlags
.None,new AsyncCallback(this.ReceivePacket),p);
}
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

syanar
Web Developer
Turkey Turkey
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWork with Wifiprofessionaljchero.sojo17-May-13 9:25 
Hi.
How I can adapt to work with Wifi?
Is it possible?
 
Best regards.
Questionhow to run projectmemberHamsasheela Sheela7-Mar-13 16:18 
hello sir
 
please tell how to run this project.i am using .net2008.I have an issue it send me an error that a project with an output type of class library cannot be started directly. in order to debug this project add an excutable project to this solution which refrences the library project. set the executable project as a startup project.
how to clear that error.please help me sir.
very urgent sir........
send mail to me email sheelaams7@gmail.com
Questionhow to correct this errormembernithyavinotha5-Jan-13 14:45 
hi sir,
 
please tell how to run this project.i am using .net2008.I have an issue it send me an error that a project with an output type of class library cannot be started directly. in order to debug this project add an excutable project to this solution which refrences the library project. set the executable project as a startup project.
how to clear that error.please help me sir.
very urgent sir........
send mail to me sir please..
gnithya1990@gmail.com
AnswerRe: how to correct this errorprofessionaljchero.sojo17-May-13 9:29 
You have to set as the startup project to SnifferUI and then run.
Greetings.
QuestionNetwork problemsmemberAJMAL SHAHZAD10-Dec-12 18:50 
what type of network problems we can solve using this application or what are advantages of this application ? D'Oh! | :doh:
Questionrunning sniferUImembersogolii14-Sep-12 6:02 
Hi
 
I can't sniff the network or open packet sniffing file. Please help me.
Questionvote 5memberboris.pong18-Jun-12 21:49 
good work!Thumbs Up | :thumbsup:
QuestionPlz help...Its urgent...so please..memberMember 901043321-May-12 23:05 
Can u please tell me which algorithms you have considered for packet decoding ????
Questionhelp mememberBelalkoochaki12-May-12 5:08 
hello sir
thanks for you
please help me to understand dll file
if you can send my dll source code
Questioncode for network sniffermemberp_oonam27-Mar-12 6:15 
someone plz mail me the code of network sniffer and connection analyzer,its causing some error in downloading the code.
QuestionRegarding Project Runmemberashishs173510-Mar-12 17:16 
Hello Sir,
please tell me how to run this intrusion detection system project and also tell me the details of this projects.
QuestionCan u provide the Documentation for this Project ?memberMember 84434032-Dec-11 2:54 
documentation will help to understand the concepts.
Generaltry execute source in win 2000\ntmemberAnil D S5-Jan-11 20:54 
try execute source in win 2000\nt
Generalproblemmemberamir_amir_amir19-Sep-10 8:41 
when i was debug the program : "An attempt was made to access a socket in a way forbidden by its access permissions"
what is problem?
GeneralIts very urgent!!!membershubhanshu1216-Apr-10 17:36 
I compiled the code in 2008 edition and its showing some error as follows:
1)CROSS-THREAD exception when I am going for 'connection checker' or any other tool this cross-thread error is coming please help me out as soon as possible coz I have my review very soon.....
GeneralProject will not compile with Visual Studio 2008 Professional C#memberspicture15-Feb-10 8:47 
This project has compiler errors in the SnifferUI module at line 1399 when compiled with Visual Studio 2008 Professional C#.
 
The code at that ocation is as follows: this.CtrlMsgs.IcmpDoubleClick += new SnifferUI.DoubleClickCallback(this.ControlDoubleClick);
 
compiler error message is as follows: D:\My Documents\Visual Studio 2008\Projects\Visual C#\Sample Programs\Network Sniffer & Conn Analyzer Class\HSSniffer\SeniorProject\SnifferUI\SnifferUI.cs(1399,60): error CS0426: The type name 'DoubleClickCallback' does not exist in the type 'SnifferUI.SnifferUI'
 
Anyone else had this problem? If so how did they get around it?
Sam Picture

GeneralRe: Project will not compile with Visual Studio 2008 Professional C#membersainulabi1-Jun-10 20:04 
using System.IO;
GeneralRe: Project will not compile with Visual Studio 2008 Professional C#memberdragonblue050219894-May-11 23:21 
I used "using System.IO", but it is not work!
 
Warning 1: Could not find type 'SnifferUI.icmpView'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built.
Warning 2: The variable 'CtrlMsgs' is either undeclared or was never assigned. E:\Giao trinh hoc tap\ky8\lap trinh mang\do an\codeproject\network sniffer and connected\HSSniffer\HSSniffer\SeniorProject\SnifferUI\SnifferUI.cs
Generalwinsock tools for server 2008memberMember 143923410-Jan-10 17:28 
does anyone knows a tools for winsock that run on server 2008?
Generaldoubtmembershubhanshu12110-Jan-10 3:40 
how many modules is this project divided into?
GeneralErrormemberabdallah2223339-Dec-09 22:14 
Dear all,
 
IP = ip;
Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.IP);
its stop in second line and give error tell is forbidden
What I should do.
 
Thanks
QuestionHow to run itmemberhunzabasharat16-Oct-09 20:55 
how to run it. i have an issue it send me an error that a project with an output type of class library cannot be started directly. in order to debug this project add an excutable project to this solution which refrences the library project. set the executable project as a startup project
kindly help me in this manner.
AnswerRe: How to run itmemberAnkur_Mundhra16-Jan-10 1:36 
U need to learn basic programming first...
 
U are trying to run a class library (The error is self explanatory).
Right click on the SnniferUI project in solution explorer and set it as a start project..
Done!!!
Generalpls tell how to run network sniffer and connection analyzer its very urgent.membernithihema30-Sep-09 18:31 
hi
sir,
i am waiting for ur reply.
its very urgent.
i need how to run this project.
GeneralDoes not 2 Network CardsmemberMember 398733021-Aug-09 3:06 
very impressive program!
 
kudos!
 
just one minor issue: though if you have 2 network cards, you cannot choose which one to use.
 
but thats easy to implement.
 
so at the bottom: this program seems really great!
GeneralRe: Does not 2 Network Cardsmemberhunzabasharat16-Oct-09 20:52 
how to run it..seems that u have run the code, i have an issue it send me an error that a project with an output type of class library cannot be started directly. in order to debug this project add an excutable project to this solution which refrences the library project. set the executable project as a startup project
kindly help me in this manner.
QuestionNeed help PLZmemberrpz7931-Mar-09 7:24 
I'm using VSPro 2005
I'm currently getting an a exeception and application crash (after stopping debugging mode) when I'm browsing (getting tcp/ip packets) and sniffing with SnifferUI. D'Oh! | :doh:
 
at snifferUI.snifferUI.counter2()
code:
void Counter2()
{
while(true)
{
foreach (string key in IdentTable_.Keys )
{
ListViewItem item = (ListViewItem)IdentTable_[key];
item.SubItems[0].Text=Convert.ToString(Counter_[key]);
}
Thread.Sleep(1200);
}

}
in bold the execption word (green box in debugger mode)
Exception:
"System.InvalidOperationException was unhandled" {Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation.}
 
In general how do I turn It to an HTTP (tcp/ip) packect sniffer instead of ICMP sniffer ?? D'Oh! | :doh:
 
Any help will be gratefully accepted
THNX ALOT^2
Roy
Roll eyes | :rolleyes:
QuestionRe: Need help PLZmemberShreyasvishwamitra31-Mar-09 16:37 
I wasnt able to compile it...............Its giving error saying only classes cannot excute it..............
 
How to execute the project...............Pls Help.
Questionlocalhost??memberShargon_8516-Feb-09 9:35 
how to get a package of local connection?
 
example
mysql 127.0.0.1
 
Thanks!:
GeneralYARDIMmemberg_sariman23-Oct-08 12:08 
iyi geceler
bitirme projesi olarak .net ile tasarsız ağlarda güvenlik projesi üzerinde çalşmaktayız.Mümkünse size bu konuda bir kaç soru sorabilirmiyim?iyi çalışmalar..
GeneralNice utilitymemberYavuz Karaman17-Sep-08 9:50 
I tried sniffing some SFTP SSH messages. SFTP uses port 22 for the destimation. What I found was that a different port was assigned everytime I connected to the destination. Also, I wasn't able to capture messages when a connection was established to the SFTP server.
 
1) It would be very convenient to just specify destination port and capture messages only from the source (any port) to destination (speific port).
2) Also, I'd like to be able to display messages in ASCII as well as Binary.
 
Nonetheless, this is highly useful.
 
Great work!
 
Y. Karaman
GeneralComment pleasemembermahmoud.elhindawy7-Sep-08 2:40 
I just ask for some helper comment to simplify hacking the code
Questionhow to execute this projectmembermurthy.vinjarapu11-May-08 20:05 
sir please help me. please tell me HOW TO EXECUTE THIS PROJECT. urgent
GeneralProjectmembersant2012329-Apr-08 18:59 
Thanks for U r Reply, I want How it is Working and I want to add Traffic Analyzer to this Module How It can be Done.Please reply.
GeneralRe: Projectmemberhyilmaz4-May-08 22:26 
Give me two days to make it work. It does't work with VS.NET's newer verisons than 2000. After that you may run it, debug some and understand how its working. ok?
 
Hakki Yilmaz

GeneralRe: Projectmemberhyilmaz6-May-08 10:10 
It take me a few hours to review code to refactor. And at the and I understood that code is full of bugs. I have to say that all code must be recoded from scratch with a threadsafe manner.. so I advise use another tool for your trafic analysis purpose Frown | :( But code fragments that capturing and parsing packets may help you if select reviewing code.
 
Hakki Yilmaz

GeneralProjectmembersant2012325-Apr-08 20:05 
I selected my Project as "Network Packet Analyzer" Please send me the Documentation of the project it is very Urgent for me.
My Email Id:sant20_123@yahoo.com.
 
SANTOSH
GeneralRe: Projectmemberhyilmaz26-Apr-08 2:21 
we don't have any documantation for the tool. If you need a document to understand how its used or how its working the article may be adaquete for the purpose. what type of document you need ?
 
Hakki Yilmaz

QuestionHow to block a packet ?memberMehdi Tirgar26-Feb-08 23:49 
It's just wonderful. Thanks for your great job Wink | ;) though I haven't test it yet, but it seems cool !
 
How can I block a TCP/UDP Packet before it reaches the software which is listening to the specified port, using C#.Net ?
 
Something like what Firewalls do ? [Clue: ALG(Aplication-layer Gateway) ???? ]
 
I would appreciate anyone's response in advance.
AnswerRe: How to block a packet ?memberhyilmaz9-Apr-08 21:31 
This may help you http://programmerworld.net/personal/firewall.htm
Here you can see you need to write code for Filter Hook Driver (Provided with Windows 2000)
and you will work with windows API's to do something you said.
The program we implemented here only catches packets and filtering here is means after getting all the bulk of packets discarding unwanted ones. Here we get packets read only manner and so you can not block packets with a program provide such a functinality
 
Hakki Yilmaz

QuestionGreat work... license info?memberdavidliew28-Jan-08 15:32 
Hi,
 
Nice work! I wonder, what's the license for this code?
Are we free to modify and re-use?
 
thanks
AnswerRe: Great work... license info?memberhyilmaz9-Apr-08 21:33 
yes you can do anything with provided code
 
Hakki Yilmaz

GeneralCoding Problem..Plss Helpmembertarun_rahul21-Dec-07 2:49 
Hi bro, i just referred your coding and created an exact same sniffer using Visual C# 2005 Express Edition. But during compilation, i got one common error which are as follows:
 
Warning 1 'System.Net.Dns.GetHostByName(string)' is obsolete: 'GetHostByName is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202' D:\DMP System\NetworkAnalyzer\NetworkAnalyzer\AddInput.Designer.cs 119 36 NetworkAnalyzer

can u help me with this problem??
 
thanks in advance bro. Smile | :) .
GeneralRe: Coding Problem..Plss Help [modified]memberhyilmaz9-Apr-08 21:39 
then you can use the advised method Smile | :)
I write a sample console app
this may help you
 
class Program
{
public static void DoGetHostEntry(string hostname)
{
IPHostEntry host;
 
host = Dns.GetHostEntry(hostname);
 
Console.WriteLine("GetHostEntry({0}) returns:", hostname);
 
foreach (IPAddress ip in host.AddressList)
{
Console.WriteLine(" {0}", ip);
}
}
 
static void Main(string[] args)
{
// I tried 127.0.0.1
// and my local machine name and its worked
DoGetHostEntry("hakki_yilmaz");
Console.ReadLine();
}
}
 
Hakki Yilmaz
modified on Thursday, April 10, 2008 3:50 AM

Generalplease tell me how to compile and run this programmembersharonstellar6-Dec-07 7:34 
Hello
 
can u let me know how to complile and run this program?
This program is really great... but i don't know where and how to run it...
 
sharon. Smile | :)
Questionhow to compile and run in visual 2005membermuzanif16-Jul-07 23:07 
can you please tel me how this code can be compiled
and how this GUI worksFrown | :(
Questionhow to compile and run in visual 2005membermuzanif16-Jul-07 23:06 
can you please tel me how this code can be compiled
and how this GUI works
GeneralSuper!memberjian.zeng3-May-07 2:36 
Big Grin | :-D
Generalit Run, but it don't show " RTBAscii" and RTBpacketmembercongthanh-dttx8-Apr-07 20:37 
Hic hic, i don't know why it run but it do not display " RTBAscii" and RTBPacket Cry | :((
NewsVS2005 ? no Problem !!membercongthanh-dttx8-Apr-07 19:51 
you got error :" cross another thread illegal....." in VS2005
Example: error at :
void Counter2()
{ while (true)
{foreach (string key in IdentTable_.Keys)
{ListViewItem item = (ListViewItem)IdentTable_[key];
item.SubItems[0].Text = Convert.ToString(Counter_[key]);
}
Thread.Sleep(1200);
}
}/////////////
You add this command TRY AND CATCH BELOW:
void Counter2()
{
try
{

while (true)
{
foreach (string key in IdentTable_.Keys)
{
ListViewItem item = (ListViewItem)IdentTable_[key];
item.SubItems[0].Text = Convert.ToString(Counter_[key]);
}
//Thread.Sleep(1200);
}
}
catch
{
CheckForIllegalCrossThreadCalls = false;
}
}///////////////
Dns.Resolve()---->Dns.GetHostEntry()
GOOD LUCK AND ENJOY

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130619.1 | Last Updated 30 Jan 2005
Article Copyright 2004 by syanar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid