现在的位置: 首页 > 综合 > 正文

如何用C#下的Raw Socket编程实现网络封包监视

2019年05月10日 ⁄ 综合 ⁄ 共 9358字 ⁄ 字号 评论关闭
楼主thtx5(thtx25)2005-03-02 10:45:59 在 .NET技术 / C# 提问

如何用C#下的Raw   Socket编程实现网络封包监视,请给出能用的源码,先谢谢各位了!!!!
问题点数:100、回复次数:23Top

1 楼thtx5(thtx25)回复于 2005-03-02 10:49:11 得分 0

网上有代码但不能编译     ,自己先顶!!Top

2 楼21xxb(人在呢)回复于 2005-03-02 10:59:25 得分 0

帮自己up一下。Top

3 楼chsfly(一蓑烟雨任平生)回复于 2005-03-02 11:03:01 得分 0

正在找这个东西,能发给我看看吗.MSN   :chsfly@hotmail.comTop

4 楼chsfly(一蓑烟雨任平生)回复于 2005-03-02 11:03:34 得分 0

一起研究一下.Top

5 楼thtx5(thtx25)回复于 2005-03-02 20:12:50 得分 0

在这里,c#的地层技术令人失望啊  
  http://fractal.blogbus.com/logs/2004/08/352576.htmlTop

6 楼gdami(糖米)回复于 2005-03-02 20:27:03 得分 0

晕菜,这个只是某本书   《C#实例技巧》   里面的一部分代码。   网上到处流传。  
  说实话,整一个没头没尾的垃圾文章。   建议你还是看这整本书好了,系统教学。  
   
 
谈起socket编程,大家也许会想起QQ和IE,没错。还有许多网络工具如P2P、NetMeeting等在应用层实现的应用程序,也是用socket
来实现的。Socket是一个网络编程接口,实现于网络应用层,Windows   Socket包括了一套系统组件,充分利用了Microsoft
  Windows  
消息驱动的特点。Socket规范1.1版是在1993年1月发行的,并广泛用于此后出现的Windows9x操作系统中。Socket规范2.2版(其
在Windows平台上的版本是Winsock2.2,也叫Winsock2)在   1996   年   5   月发行,Windows  
NT  
5.0及以后版本的Windows系统支持Winsock2,在Winsock2中,支持多个传输协议的原始套接字,重叠I/O模型、服务质量控制等。
 
  ........................................................................  
  Top

7 楼hddhddhdd(还刀的)回复于 2005-03-02 21:16:10 得分 0

帮顶Top

8 楼web_gus(树欲静而风不止)回复于 2005-03-02 21:32:48 得分 0

upTop

9 楼isaacyh(发现自己啥都不懂。。。回头学C++)回复于 2005-03-03 09:00:52 得分 0

这个好像只能到IP包这一层。。。  
   
  只能得到这层的数据,再外面的就不是用C#写了,所以感觉C#做不到sniffer那样的效果的。。。  
   
  如果有高手知道,请告诉一声的说。。。Top

10 楼thtx5(thtx25)回复于 2005-03-03 14:51:19 得分 0

delphi可以作到   可是没法升级到net下面,delphi2005我没法把delphi6的工程编译成net下的程序,谁成功了,发份代码吧谢谢Top

11 楼yuqingjiang()回复于 2005-03-03 14:52:29 得分 100

C#底层技术不弱。  
  操作系统级的socket嵌套字最底层只能拦截到IP包,要拦截含数据链路层的包,需要网卡的绑定与控制.sniffer和防火墙等软件的原理就是这样。  
  以下是侦听代码:`  
  using   System;  
  using   System.Net;  
  using   System.Net.Sockets;  
  using   System.Text;  
   
  namespace   WindowsApplication1  
  {  
   
  public   class   PacketArrivedEventArgs:System.EventArgs  
  {  
  public   PacketArrivedEventArgs()  
  {  
  }  
  public   uint   HeaderLength   =   0;    
  public   string   Protocol   =   String.Empty;  
  public   string   IPVersion   =   String.Empty;  
  public   string   OriginationAddress   =   String.Empty;  
  public   string   OriginationPort   =   String.Empty;  
  public   string   DestinationAddress   =   String.Empty;  
  public   string   DestinationPort   =   String.Empty;  
  public   uint   PacketLength   =   0;  
  public   uint   MessageLength   =   0;  
  public   byte[]   ReceiveBuffer   =   null;  
  public   byte[]   IPHeaderBuffer   =   null;  
  public   byte[]   MessageBuffer   =   null;  
   
  }  
   
  ///   <summary>  
  ///   MyTryRaw   的摘要说明。  
  ///   </summary>  
  public   class   MyTryRaw  
  {  
  #region   Attributes  
   
  private   static   int   len_receive_buf;   //得到的数据流的长度  
  private   byte   []   receive_buf_bytes   =   null;                     //收到的字节  
  private   Socket   socket   =   null;               //声明套接字  
  private   const   int   SIO_RCVALL   =   unchecked((int)0x98000001);//监听所有的数据包  
  public   static   bool   isStop   =   false;  
   
  public   Socket   m_socket  
  {  
  get  
  {  
  return   socket;  
  }  
  }  
   
  #endregion  
   
  #region   Events  
  public   delegate   void   PacketArrivedEventHandler(Object   sender,   PacketArrivedEventArgs   args);  
   
  public   event   PacketArrivedEventHandler   PacketArrival;  
  #endregion    
   
  #region   OnEvents  
  protected   virtual   void   OnPacketArrival(PacketArrivedEventArgs   e)  
  {  
  if(PacketArrival   !=   null)  
  {  
  PacketArrival(this,e);  
  }  
   
  }  
   
  #endregion    
   
  #region   Constructor  
  public   MyTryRaw()  
  {  
  //  
  //   TODO:   在此处添加构造函数逻辑  
  //  
  len_receive_buf   =   4096;  
  receive_buf_bytes   =   new   byte[len_receive_buf];  
  PacketArrival   +=   new   PacketArrivedEventHandler(MyTryRaw_PacketArrival);  
   
  }  
  #endregion  
   
  #region   Functions  
   
  public   void   BindSocket()  
  {  
  IPAddress   ipAddress   =   IPAddress.Parse("192.168.1.157");  
  this.socket   =   new   Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.IP);  
  Console.WriteLine("Start   bind!");  
  try  
  {  
  socket.Blocking   =   false;  
  socket.Bind(new   IPEndPoint(ipAddress,3721));  
  }  
  catch(Exception   E)  
  {  
  throw(E);  
  }  
   
   
  Console.WriteLine("Bind   success!");  
  }  
   
  public   void   SetOption()  
  {  
  Console.WriteLine("Start   SetOption!");  
  try  
  {  
  socket.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.HeaderIncluded,1);  
  byte   []IN   =   new   byte[4]{1,   0,   0,   0};  
  byte   []OUT   =   new   byte[4];    
  int   ret_code   =   -1;  
  ret_code   =   socket.IOControl(SIO_RCVALL,   IN,   OUT);  
  ret_code   =   OUT[0]   +   OUT[1]   +   OUT[2]   +   OUT[3];  
  }  
  catch(Exception   E)  
  {  
  throw(E);  
  }  
  Console.WriteLine("SetOption   success!");  
  }  
   
  public   void   ShutDown()  
  {  
  Console.WriteLine("Start   ShutDown");  
  if(socket   !=   null)  
  {  
  socket.Shutdown(SocketShutdown.Both);  
  socket.Close();  
  }  
  socket   =   null;  
  Console.WriteLine("ShutDown   Success");  
  }  
   
  Top

12 楼yuqingjiang()回复于 2005-03-03 14:52:40 得分 0

public   void   Receive(byte[]   receivedBytes,int   receivedLength)  
  {  
  PacketArrivedEventArgs   e   =   new   PacketArrivedEventArgs();  
   
  int   IPVersion   =   Convert.ToInt16((receivedBytes[0]&0xF0)>>4);  
  e.IPVersion   =   IPVersion.ToString();  
   
  e.HeaderLength   =   Convert.ToUInt32((receivedBytes[0]   &   0x0F)   <<   2);  
   
  if(receivedBytes.Length   >=   20)  
  {  
  switch(Convert.ToInt16(receivedBytes[9]))  
  {  
  case   1:  
  e.Protocol   =   "ICMP";  
  break;  
  case   2:  
  e.Protocol   =   "IGMP";  
  break;  
  case   6:  
  e.Protocol   =   "TCP";  
  break;  
  case   17:  
  e.Protocol   =   "UDP";  
  break;  
  default:  
  e.Protocol   =   "Unknow";  
  break;  
  }  
   
  e.OriginationAddress   =  
Convert.ToInt16(receivedBytes[12]).ToString()+"."+Convert.ToInt16(receivedBytes[13]).ToString()+"."+Convert.ToInt16(receivedBytes[14]).ToString()+"."+Convert.ToInt16(receivedBytes[15]).ToString();
 
  e.DestinationAddress   =  
Convert.ToInt16(receivedBytes[16]).ToString()+"."+Convert.ToInt16(receivedBytes[17]).ToString()+"."+Convert.ToInt16(receivedBytes[18]).ToString()+"."+Convert.ToInt16(receivedBytes[19]).ToString();
 
   
  int   Oport   =   ((receivedBytes[20]<<8)+receivedBytes[21]);  
  e.OriginationPort   =   Oport.ToString();  
   
  int   Dport   =   ((receivedBytes[22]<<8)+receivedBytes[23]);  
  e.DestinationPort   =   Dport.ToString();  
   
  e.PacketLength   =   (uint)receivedLength;  
   
  e.MessageLength   =   e.PacketLength   -   e.HeaderLength;  
   
  e.ReceiveBuffer   =   new   byte[e.PacketLength];  
  e.IPHeaderBuffer   =   new   byte[e.HeaderLength];  
  e.MessageBuffer   =   new   byte[e.MessageLength];  
   
  Array.Copy(receivedBytes,0,e.ReceiveBuffer,0,(int)e.PacketLength);  
   
  Array.Copy(receivedBytes,0,e.IPHeaderBuffer,0,e.HeaderLength);  
   
  Array.Copy(receivedBytes,e.HeaderLength,e.MessageBuffer,0,(int)e.MessageLength);  
  }  
   
  OnPacketArrival(e);  
   
  }  
   
  public   void   BeginReceive()  
  {  
   
  if(socket   !=   null)  
  {  
  object   state   =   null;  
  state   =   socket;  
 
socket.BeginReceive(receive_buf_bytes,0,receive_buf_bytes.Length,SocketFlags.None,new
  AsyncCallback(CallReceive),state);  
  }  
  }  
   
  private   void   CallReceive(IAsyncResult   ar)//异步回调  
  {  
  int   received_bytes   =   0;  
  Socket   m_socket   =   (Socket)ar.AsyncState;  
  if(m_socket   !=   null)  
  {  
  if(isStop   ==   false)  
  {  
  received_bytes   =   socket.EndReceive(ar);    
   
  Receive(receive_buf_bytes,   received_bytes);  
  }  
  if(isStop   ==   false)  
  {  
  BeginReceive();  
  }  
  }  
  }  
   
   
  private   void   MyTryRaw_PacketArrival(Object   sender,   PacketArrivedEventArgs   e)  
  {  
   
  Console.WriteLine("Start   Show-------------");  
  Console.WriteLine("HeaderLength:   "+e.HeaderLength);  
  Console.WriteLine("IPHeader:   ");  
  for(int   i   =   0;   i<e.IPHeaderBuffer.Length;   i++)  
  {  
  int   j   =   i%16;  
  if(i>=16   &&   j   ==   0)  
  {  
  Console.WriteLine("/r/n");  
  }  
   
  if(e.IPHeaderBuffer[i].ToString("X").Length   !=   1)  
  {  
  Console.Write("{0}   ",e.IPHeaderBuffer[i].ToString("X"));  
  }  
  else  
  {  
  Console.Write("0{0}   ",e.IPHeaderBuffer[i].ToString("X"));  
  }  
   
  }  
  Console.WriteLine("/r/n");  
   
  Console.WriteLine("IPVersion:   "+e.IPVersion);  
  Console.WriteLine("OriginAddress:   "+e.OriginationAddress);  
  Console.WriteLine("OriginPort:   "+e.OriginationPort);  
  Console.WriteLine("DestAddress:   "+e.DestinationAddress);  
  Console.WriteLine("DestPort:   "+e.DestinationPort);  
  Console.WriteLine("Protocol:   "+e.Protocol);  
   
  Console.WriteLine("PacketLength:   "+e.PacketLength);  
  Console.WriteLine("Packet:   ");  
  for(int   i   =   0;   i<e.ReceiveBuffer.Length;   i++)  
  {  
  int   j   =   i%16;  
  if(i>=16   &&   j   ==   0)  
  {  
  Console.WriteLine("/r/n");  
  }  
   
  if(e.ReceiveBuffer[i].ToString("X").Length   !=   1)  
  {  
  Console.Write("{0}   ",e.ReceiveBuffer[i].ToString("X"));  
  }  
  else  
  {  
  Console.Write("0{0}   ",e.ReceiveBuffer[i].ToString("X"));  
  }  
   
  }  
  Console.WriteLine("/r/n");  
   
  Console.WriteLine("MessageLength:   "+e.MessageLength);  
  Console.WriteLine("Message:   ");  
  for(int   i   =   0;   i<e.MessageBuffer.Length;   i++)  
  {  
  int   j   =   i%16;  
  if(i>=16   &&   j   ==   0)  
  {  
  Console.WriteLine("/r/n");  
  }  
  if(e.MessageBuffer[i].ToString("X").Length   !=   1)  
  {  
  Console.Write("{0}   ",e.MessageBuffer[i].ToString("X"));  
  }  
  else  
  {  
  Console.Write("0{0}   ",e.MessageBuffer[i].ToString("X"));  
  }  
   
  }  
  Console.WriteLine("/r/n");  
  Console.WriteLine("----------------End   Show!");  
  Console.WriteLine("----------------");  
  Console.WriteLine("/r/n");  
  Console.WriteLine("/r/n");  
  }  
  #endregion  
  }  
  }  
  Top

13 楼thtx5(thtx25)回复于 2005-03-03 14:57:46 得分 0

我就是在网上看的代码,确实没头没尾,不管他了。     可封包截取这活儿,   c#这吹的没边的语言应该可以胜任吧,如果不能,我们还不如用c++编了,费时间学c#干吗,高层的delphi、c++builder同样可以做的很好。Top

14 楼thtx5(thtx25)回复于 2005-03-03 15:04:16 得分 0

呵呵好长,研究中!!!!Top

15 楼isaacyh(发现自己啥都不懂。。。回头学C++)回复于 2005-03-03 15:32:53 得分 0

呵呵,yuqingjiang()   手里肯定有源码的说。。。  
   
  Top

16 楼thtx5(thtx25)回复于 2005-03-03 21:31:08 得分 0

不好意思我是新手,   yuqingjiang能不能发个完整源码,谢谢。thtx50207@sina.comTop

17 楼CWYCN(小卫)回复于 2005-03-03 23:06:36 得分 0

这好象只能得到主机所有接收到的包,而发送的就得不到了,请高手指点Top

18 楼yuqingjiang()回复于 2005-03-04 09:12:51 得分 0

To   thx5(thtx25):  
  邮件已发送  
  To   CWYCN(小卫):  
  可以得到发出包,刚测试过了。  
   
  此段代码的功能:监听网络上通过主机的所有数据包,无论通信双方地址是否含主机。Top

19 楼amendajing(学习,是个漫长的旅途!)回复于 2005-03-04 09:34:19 得分 0

markTop

20 楼thtx5(thtx25)回复于 2005-03-04 09:44:46 得分 0

真热闹!!!!看来要晚些结贴了Top

21 楼thtx5(thtx25)回复于 2005-03-04 17:24:56 得分 0

搞定了,谢谢大家了!!!!!!Top

22 楼zhioy()回复于 2005-03-04 17:35:17 得分 0

gzTop

23 楼kmyhy(颐和园)回复于 2005-03-04 19:12:25 得分 0

根据数小时的测试,未发现yuqingjiang的程序可以嗅探到发往其他主机的包。但确实可以拦截到本地主机发送/接受的包,以及发往广播地址的包

抱歉!评论已关闭.