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
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; namespace RawSocket ... { /// <summary> /// @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(); } }}
使用方法:
public static void Main(String[] args) ... { RawSocket socket = new RawSocket(); socket.Run(); }