raw socket 三部曲:
socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0));
同步下:rcv_size = socket.Receive(buffer);
异步下:socket.Begin***
实现过程不难,难点是捕获后对数据报的分析,过滤的工作。
ps:网络层ip数据报格式如下:ip header+××header(如TCP header) + Data
今天存在问题如下:嗅觉不灵敏,不知道是设置不对还是raw socket效果本身就是这样,等待考究……
今天研究到此结束,待续……
附代码:
RawSocket.cs










/// <summary>
/// @author segment
/// @author segment
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct IpHeader

...{
[FieldOffset(0)]
public byte ip_verlen; // IP version and IP Header length
[FieldOffset(1)]
public byte ip_tos; // Type of service
[FieldOffset(2)]
public ushort ip_totallength; // total length of the packet
[FieldOffset(4)]
public ushort ip_id; // unique identifier
[FieldOffset(6)]
public ushort ip_offset; // flags and offset
[FieldOffset(8)]
public byte ip_ttl; // Time To Live
[FieldOffset(9)]
public byte ip_protocol; // protocol (TCP, UDP etc)
[FieldOffset(10)]
public ushort ip_checksum; //IP Header checksum
[FieldOffset(12)]
public uint ip_srcaddr; //Source address
[FieldOffset(16)]
public uint ip_destaddr;//Destination Address
}

class RawSocket

...{
Socket socket;
String IP = "218.20.242.189";
private String StandardIP(uint ip)

...{
byte[] b_ip = new byte[4];
b_ip[0] = (byte)(ip & 0x000000ff);
b_ip[1] = (byte)((ip & 0x0000ff00) >> 8);
b_ip[2] = (byte)((ip & 0x00ff0000)>>16);
b_ip[3] = (byte)((ip & 0xff000000)>>24);
return b_ip[0].ToString() + "." + b_ip[1].ToString() + "." + b_ip[2].ToString() + "." + b_ip[3].ToString();
}
unsafe private void ParseReceive(byte[]buffer,int size)

...{
if (buffer == null) return;
fixed (byte*pbuffer = buffer)

...{
IpHeader* ip_header = (IpHeader*)pbuffer;
int protocol = ip_header->ip_protocol;
uint ip_srcaddr = ip_header->ip_srcaddr, ip_destaddr = ip_header->ip_destaddr, header_len = 0;
string out_string = "";
short src_port = 0, dst_port = 0;
IPAddress tmp_ip;
string from_ip="", to_ip="";
from_ip = ip_header->ip_srcaddr.ToString();
switch (protocol)

...{
case 1: out_string = "ICMP:"; break;
case 2: out_string = "IGMP:"; break;
case 6:
out_string = "TCP:";
break;
case 17: out_string = "UDP:";
break;
default: out_string = "UNKNOWN"; break;
}
// System.Console.WriteLine(out_string + "from ip:" + IPAddress.Parse(from_ip).ToString() + " to ip:" + IPAddress.Parse(to_ip).ToString());
System.Console.WriteLine(out_string + "src:" + StandardIP(ip_srcaddr) + "dest:" + StandardIP(ip_destaddr));
}
}
public void ShutDown()

...{
if(socket != null)

...{
try

...{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch(Exception)

...{
System.Console.WriteLine("关闭socket错误!");
}

}
}
public void Run()

...{
System.Console.WriteLine("Raw Socket running...");
socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
byte[] buffer = new byte[4096];
int rcv_size = 0;
// socket.Blocking = false;
socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0));
while (true)

...{
System.Console.WriteLine("开始新一次循环");
try

...{
//socket.BeginReceive(buffer, 0, 10, SocketFlags.None, Callback, null);
rcv_size = socket.Receive(buffer);
ParseReceive(buffer, rcv_size);
}
catch (Exception e)

...{
System.Console.WriteLine("异常:" + e.Message);
return;
}
//System.Threading.Thread.Sleep(500);
//System.Console.WriteLine("接收到:" + rcv_size.ToString());
}
}
~RawSocket()

...{
ShutDown();
}
}
}



































































































































使用方法:






