art_Form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
namespace WindowsFormsApplication
{
public enum Protocol
{
TCP = 6,
UDP = 17,
Unknown = -1
};
public partial class art_Form : System.Windows.Forms.Form
{
private Socket mainSocket; //The socket which captures all incoming packets
private byte[] byteData = new byte[4096];
private bool bContinueCapturing = false; //A flag to check if packets are to be captured or not
private delegate void AddTreeNode(TreeNode node);
public art_Form()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (cmbInterfaces.Text == "")
{
MessageBox.Show("Select an Interface to capture the packets.", "art1sts sniffer",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
if (!bContinueCapturing)
{
//Start capturing the packets...
btnStart.Text = "Stop";
bContinueCapturing = true;
//For sniffing the socket to capture the packets has to be a raw socket, with the
//address family being of type internetwork, and protocol being IP
mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.IP);
//Bind the socket to the selected IP address
mainSocket.Bind(new IPEndPoint(IPAddress.Parse(cmbInterfaces.Text), 0));
//Set the socket options
mainSocket.SetSocketOption(SocketOptionLevel.IP, //Applies only to IP packets
SocketOptionName.HeaderIncluded, //Set the include the header
true); //option to true
byte[] byTrue = new byte[4] { 1, 0, 0, 0 };
byte[] byOut = new byte[4] { 1, 0, 0, 0 }; //Capture outgoing packets
//Socket.IOControl is analogous to the WSAIoctl method of Winsock 2
mainSocket.IOControl(IOControlCode.ReceiveAll, //Equivalent to SIO_RCVALL constant
//of Winsock 2
byTrue,
byOut);
//Start receiving the packets asynchronously
mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(OnReceive), null);
}
else
{
btnStart.Text = "&Start";
bContinueCapturing = false;
//To stop capturing the packets close the socket
mainSocket.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "art1stssniffer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void OnReceive(IAsyncResult ar)
{
try
{
int nReceived = mainSocket.EndReceive(ar);
//Analyze the bytes received...
ParseData(byteData, nReceived);
if (bContinueCapturing)
{
byteData = new byte[4096];
//Another call to BeginReceive so that we continue to receive the incoming
//packets
mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(OnReceive), null);
}
}
catch (ObjectDisposedException)
{
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "art1sts sniffer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ParseData(byte[] byteData, int nReceived)
{
TreeNode rootNode = new TreeNode();
//Since all protocol packets are encapsulated in the IP datagram
//so we start by parsing the IP header and see what protocol data
//is being carried by it
IPHeader ipHeader = new IPHeader(byteData, nReceived);
TreeNode ipNode = MakeIPTreeNode(ipHeader);
rootNode.Nodes.Add(ipNode);
//Now according to the protocol being carried by the IP datagram we parse
//the data field of the datagram
switch (ipHeader.ProtocolType)
{
case Protocol.TCP:
TCPHeader tcpHeader = new TCPHeader(ipHeader.Data, //IPHeader.Data stores the data being
//carried by the IP datagram
ipHeader.MessageLength);//Length of the data field
TreeNode tcpNode = MakeTCPTreeNode(tcpHeader);
rootNode.Nodes.Add(tcpNode);
//If the port is equal to 53 then the underlying protocol is DNS
//Note: DNS can use either TCP or UDP thats why the check is done twice
if (tcpHeader.DestinationPort == "53" || tcpHeader.SourcePort == "53")
{
TreeNode dnsNode = MakeDNSTreeNode(tcpHeader.Data, (int)tcpHeader.MessageLength);
rootNode.Nodes.Add(dnsNode);
}
break;
case Protocol.UDP:
UDPHeader udpHeader = new UDPHeader(ipHeader.Data, //IPHeader.Data stores the data being
//carried by the IP datagram
(int)ipHeader.MessageLength);//Length of the data field
TreeNode udpNode = MakeUDPTreeNode(udpHeader);
rootNode.Nodes.Add(udpNode);
//If the port is equal to 53 then the underlying protocol is DNS
//Note: DNS can use either TCP or UDP thats why the check is done twice
if (udpHeader.DestinationPort == "53" || udpHeader.SourcePort == "53")
{
TreeNode dnsNode = MakeDNSTreeNode(udpHeader.Data,
//Length of UDP header is always eight bytes so we subtract that out of the total
//length to find the length of the data
Convert.ToInt32(udpHeader.Length) - 8);
rootNode.Nodes.Add(dnsNode);
}
break;
case Protocol.Unknown:
break;
}
AddTreeNode addTreeNode = new AddTreeNode(OnAddTreeNode);
rootNode.Text = ipHeader.SourceAddress.ToString() + "-" +
ipHeader.DestinationAddress.ToString();
//Thread safe adding of the nodes
treeView.Invoke(addTreeNode, new object[] { rootNode });
}
//Helper function which returns the information contained in the IP header as a
//tree node
private TreeNode MakeIPTreeNode(IPHeader ipHeader)
{
TreeNode ipNode = new TreeNode();
ipNode.Text = "IP";
ipNode.Nodes.Add("Ver: " + ipHeader.Version);
ipNode.Nodes.Add("Header Length: " + ipHeader.HeaderLength);
ipNode.Nodes.Add("Differntiated Services: " + ipHeader.DifferentiatedServices);
ipNode.Nodes.Add("Total Length: " + ipHeader.TotalLength);
ipNode.Nodes.Add("Identification: " + ipHeader.Identification);
ipNode.Nodes.Add("Flags: " + ipHeader.Flags);
ipNode.Nodes.Add("Fragmentation Offset: " + ipHeader.FragmentationOffset);
ipNode.Nodes.Add("Time to live: " + ipHeader.TTL);
switch (ipHeader.ProtocolType)
{
case Protocol.TCP:
ipNode.Nodes.Add("Protocol: " + "TCP");
break;
case Protocol.UDP:
ipNode.Nodes.Add("Protocol: " + "UDP");
break;
case Protocol.Unknown:
ipNode.Nodes.Add("Protocol: " + "Unknown");
break;
}
ipNode.Nodes.Add("Checksum: " + ipHeader.Checksum);
ipNode.Nodes.Add("Source: " + ipHeader.SourceAddress.ToString());
ipNode.Nodes.Add("Destination: " + ipHeader.DestinationAddress.ToString());
return ipNode;
}
//Helper function which returns the information contained in the TCP header as a
//tree node
private TreeNode MakeTCPTreeNode(TCPHeader tcpHeader)
{
TreeNode tcpNode = new TreeNode();
tcpNode.Text = "TCP";
tcpNode.Nodes.Add("Source Port: " + tcpHeader.SourcePort);
tcpNode.Nodes.Add("Destination Port: " + tcpHeader.DestinationPort);
tcpNode.Nodes.Add("Sequence Number: " + tcpHeader.SequenceNumber);
if (tcpHeader.AcknowledgementNumber != "")
tcpNode.Nodes.Add("Acknowledgement Number: " + tcpHeader.AcknowledgementNumber);
tcpNode.Nodes.Add("Header Length: " + tcpHeader.HeaderLength);
tcpNode.Nodes.Add("Flags: " + tcpHeader.Flags);
tcpNode.Nodes.Add("Window Size: " + tcpHeader.WindowSize);
tcpNode.Nodes.Add("Checksum: " + tcpHeader.Checksum);
if (tcpHeader.UrgentPointer != "")
tcpNode.Nodes.Add("Urgent Pointer: " + tcpHeader.UrgentPointer);
return tcpNode;
}
//Helper function which returns the information contained in the UDP header as a
//tree node
private TreeNode MakeUDPTreeNode(UDPHeader udpHeader)
{
TreeNode udpNode = new TreeNode();
udpNode.Text = "UDP";
udpNode.Nodes.Add("Source Port: " + udpHeader.SourcePort);
udpNode.Nodes.Add("Destination Port: " + udpHeader.DestinationPort);
udpNode.Nodes.Add("Length: " + udpHeader.Length);
udpNode.Nodes.Add("Checksum: " + udpHeader.Checksum);
return udpNode;
}
//Helper function which returns the information contained in the DNS header as a
//tree node
private TreeNode MakeDNSTreeNode(byte[] byteData, int nLength)
{
DNSHeader dnsHeader = new DNSHeader(byteData, nLength);
TreeNode dnsNode = new TreeNode();
dnsNode.Text = "DNS";
dnsNode.Nodes.Add("Identification: " + dnsHeader.Identification);
dnsNode.Nodes.Add("Flags: " + dnsHeader.Flags);
dnsNode.Nodes.Add("Questions: " + dnsHeader.TotalQuestions);
dnsNode.Nodes.Add("Answer RRs: " + dnsHeader.TotalAnswerRRs);
dnsNode.Nodes.Add("Authority RRs: " + dnsHeader.TotalAuthorityRRs);
dnsNode.Nodes.Add("Additional RRs: " + dnsHeader.TotalAdditionalRRs);
return dnsNode;
}
private void OnAddTreeNode(TreeNode node)
{
treeView.Nodes.Add(node);
}
private void SnifferForm_Load(object sender, EventArgs e)
{
string strIP = null;
IPHostEntry HosyEntry = Dns.GetHostEntry((Dns.GetHostName()));
if (HosyEntry.AddressList.Length > 0)
{
foreach (IPAddress ip in HosyEntry.AddressList)
{
strIP = ip.ToString();
cmbInterfaces.Items.Add(strIP);
}
}
}
private void
_Load(object sender, EventArgs e)
{
string strIP = null;
IPHostEntry HosyEntry = Dns.GetHostEntry((Dns.GetHostName()));
if (HosyEntry.AddressList.Length > 0)
{
foreach (IPAddress ip in HosyEntry.AddressList)
{
strIP = ip.ToString();
cmbInterfaces.Items.Add(strIP);
}
}
}
private void label1_Click(object sender, EventArgs e)
{
}
private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
}
private void cmbInterfaces_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
art_Form.Designer.cs
namespace WindowsFormsApplication
{
partial class art_Form
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form 디자이너에서 생성한 코드
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.btnStart = new System.Windows.Forms.Button();
this.cmbInterfaces = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.treeView = new System.Windows.Forms.TreeView();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.BackColor = System.Drawing.SystemColors.Window;
this.btnStart.Font = new System.Drawing.Font("맑은 고딕", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.btnStart.Location = new System.Drawing.Point(749, 1);
this.btnStart.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(194, 64);
this.btnStart.TabIndex = 1;
this.btnStart.Text = "start";
this.btnStart.UseVisualStyleBackColor = false;
this.btnStart.Click += new System.EventHandler(this.button1_Click);
//
// cmbInterfaces
//
this.cmbInterfaces.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbInterfaces.FormattingEnabled = true;
this.cmbInterfaces.Location = new System.Drawing.Point(12, 20);
this.cmbInterfaces.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.cmbInterfaces.Name = "cmbInterfaces";
this.cmbInterfaces.Size = new System.Drawing.Size(731, 23);
this.cmbInterfaces.TabIndex = 2;
this.cmbInterfaces.SelectedIndexChanged += new System.EventHandler(this.cmbInterfaces_SelectedIndexChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 1);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(93, 15);
this.label1.TabIndex = 3;
this.label1.Text = "Made by art1sts";
this.label1.Click += new System.EventHandler(this.label1_Click);
//
// treeView
//
this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.treeView.ItemHeight = 14;
this.treeView.Location = new System.Drawing.Point(-54, 262);
this.treeView.Name = "treeView";
this.treeView.Size = new System.Drawing.Size(931, 503);
this.treeView.TabIndex = 0;
this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
//
// art_Form
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Window;
this.ClientSize = new System.Drawing.Size(947, 575);
this.Controls.Add(this.treeView);
this.Controls.Add(this.label1);
this.Controls.Add(this.cmbInterfaces);
this.Controls.Add(this.btnStart);
this.Font = new System.Drawing.Font("맑은 고딕", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.Name = "art_Form";
this.Text = "art capture";
this.Load += new System.EventHandler(this.SnifferForm_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.ComboBox cmbInterfaces;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TreeView treeView;
}
}
program.cs
using System;
using System.Windows.Forms;
using System.Collections.Generic;
namespace WindowsFormsApplication
{
static class Program
{
/// <summary>
/// 해당 응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new art_Form());
}
}
}
'Programing > C' 카테고리의 다른 글
구조체와 클래스의 차이점 (1) | 2016.06.18 |
---|---|
[C언어] 연산자 / 연산자 우선순위 (0) | 2016.05.11 |