[Mono-devel-list] Raw socket sniffer with Mono on Linux

=?big5?B?pP2359l5?= robin at netnifty.com.tw
Wed May 18 23:31:38 EDT 2005


Hi,

I got an exception when doing socket.IOControl(SIO_RCVALL, IN, OUT) with Mono on Linux,
It works well on Windows platform,
It seems int SIO_RCVALL = unchecked((int)0x98000001) is not in Linux ioctl_list,
How can I fix the code below to work on Linux?
Thanks.

//This file contains the RawSocket class.  The goal of this class is
to have a generic packet
//sniffing kind of class that fires events when an incoming IP packet
is received.  The event
//gives the user access to everything contained in the IP packet and
hopefully makes creating
//your own packet sniffer quite easy.  The event args returned with
the event give the user of
//the class access to things like the from and to IP address, ports,
protocol, etc. and even the
//contents of the message in the form of a byte array.


namespace ReceiveAll
{
	using System;
	using System.Net;
	using System.Net.Sockets;
	using System.Runtime.InteropServices;

	
	[StructLayout(LayoutKind.Explicit)]
	public struct IPHeader
	{
		[FieldOffset(0)] public byte    ip_verlen; //IP version and IP
Header length Combined
		[FieldOffset(1)] public byte    ip_tos; //Type of Service
		[FieldOffset(2)] public ushort  ip_totallength; //Total Packet Length
		[FieldOffset(4)] public ushort  ip_id; //Unique ID
		[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,
ICMP, Etc.)
		[FieldOffset(10)] public ushort ip_checksum; //IP Header Checksum
		[FieldOffset(12)] public uint   ip_srcaddr; //Source IP Address
		[FieldOffset(16)] public uint   ip_destaddr; //Destination IP Address
	}

	public class RawSocket
	{
		private bool error_occurred;
		public bool KeepRunning;
		private static int len_receive_buf;
		byte [] receive_buf_bytes;
		private Socket socket = null; 

		public RawSocket()
		{
			error_occurred=false;
			len_receive_buf = 4096;
			receive_buf_bytes = new byte[len_receive_buf];
		}
		
		public void CreateAndBindSocket(string IP)
		{
			socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.IP);
			socket.Blocking = false;
			socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0));

			if (SetSocketOption()==false) error_occurred=true;
		}

		public void Shutdown()
		{
			if(socket != null)
			{
				socket.Shutdown(SocketShutdown.Both);
				socket.Close();
			}
		}

		private bool SetSocketOption()
		{
			bool ret_value = true;
			try
			{
				socket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.HeaderIncluded, 1);
    
				byte []IN = new byte[4]{1, 0, 0, 0};
				byte []OUT = new byte[4];
				int SIO_RCVALL = unchecked((int)0x98000001);
				int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
				ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];
				if(ret_code != 0) ret_value = false;
			}
			catch(SocketException)
			{
				ret_value = false;
			}
			return ret_value;
		}

		public bool ErrorOccurred
		{
			get
			{
				return error_occurred;
			}
		}

		unsafe private void Receive(byte [] buf, int len)
		{
			byte temp_protocol=0;
			uint temp_version=0;
			uint temp_ip_srcaddr=0;
			uint temp_ip_destaddr=0;
			short temp_srcport=0;
			short temp_dstport=0;
            IPAddress temp_ip;
			
			PacketArrivedEventArgs e=new PacketArrivedEventArgs();

			fixed(byte *fixed_buf = buf)
			{
				IPHeader * head = (IPHeader *) fixed_buf;
				e.HeaderLength=(uint)(head->ip_verlen & 0x0F) << 2;
				
				temp_protocol = head->ip_protocol;
				switch(temp_protocol)
				{
					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= "UNKNOWN"; break;
				}

				temp_version =(uint)(head->ip_verlen & 0xF0) >> 4;
				e.IPVersion = temp_version.ToString();

                temp_ip_srcaddr = head->ip_srcaddr;
				temp_ip_destaddr = head->ip_destaddr;
				temp_ip = new IPAddress(temp_ip_srcaddr);
				e.OriginationAddress =temp_ip.ToString();
				temp_ip = new IPAddress(temp_ip_destaddr);
				e.DestinationAddress = temp_ip.ToString();

				temp_srcport = *(short *)&fixed_buf[e.HeaderLength];
				temp_dstport = *(short *)&fixed_buf[e.HeaderLength+2];
			
e.OriginationPort=IPAddress.NetworkToHostOrder(temp_srcport).ToString();
			
e.DestinationPort=IPAddress.NetworkToHostOrder(temp_dstport).ToString();

				e.PacketLength =(uint)len;
				e.MessageLength =(uint)len - e.HeaderLength;

				e.ReceiveBuffer=buf;
				Array.Copy(buf,0,e.IPHeaderBuffer,0,(int)e.HeaderLength);
			
Array.Copy(buf,(int)e.HeaderLength,e.MessageBuffer,0,(int)e.MessageLength);
 			}
			
			OnPacketArrival(e);
		}
  
		public void Run() 
		{
			IAsyncResult ar = socket.BeginReceive(receive_buf_bytes, 0,
len_receive_buf, SocketFlags.None, new AsyncCallback(CallReceive), this);
		}

		private void CallReceive(IAsyncResult ar)
		{
			try
			{
				int received_bytes;
				received_bytes = socket.EndReceive(ar); 
				Receive(receive_buf_bytes, received_bytes);
			}
			catch {} //ignore all network errors ;)
			if (KeepRunning) Run();
		}

		public class PacketArrivedEventArgs : EventArgs 
		{
			public PacketArrivedEventArgs() 
			{
				this.protocol = "";
				this.destination_port  = "";
				this.origination_port  = "";
				this.destination_address  = "";
				this.origination_address  = "";
				this.ip_version  = "";

				this.total_packet_length =0;
				this.message_length =0;
				this.header_length =0;

				this.receive_buf_bytes=new byte[len_receive_buf];
				this.ip_header_bytes=new byte[len_receive_buf];
				this.message_bytes=new byte[len_receive_buf];
			}

			public string Protocol
			{
				get {return protocol;}
				set {protocol=value;}
			}
			public string DestinationPort
			{
				get {return destination_port;}
				set {destination_port=value;}
			}
			public string OriginationPort
			{
				get {return origination_port;}
				set {origination_port=value;}
			}
			public string DestinationAddress
			{
				get {return destination_address;}
				set {destination_address=value;}
			}
			public string OriginationAddress
			{
				get {return origination_address;}
				set {origination_address=value;}
			}
			public string IPVersion
			{
				get {return ip_version;}
				set {ip_version=value;}
			}
			public uint PacketLength
			{
				get {return total_packet_length;}
				set {total_packet_length=value;}
			}
			public uint MessageLength
			{
				get {return message_length;}
				set {message_length=value;}
			}
			public uint HeaderLength
			{
				get {return header_length;}
				set {header_length=value;}
			}
			public byte [] ReceiveBuffer
			{
				get {return receive_buf_bytes;}
				set {receive_buf_bytes=value;}
			}
			public byte [] IPHeaderBuffer
			{
				get {return ip_header_bytes;}
				set {ip_header_bytes=value;}
			}
			public byte [] MessageBuffer
			{
				get {return message_bytes;}
				set {message_bytes=value;}
			}
			private string protocol;
			private string destination_port;
			private string origination_port;
			private string destination_address;
			private string origination_address;
			private string ip_version;
			private uint total_packet_length;
			private uint message_length;
			private uint header_length;
			private byte []receive_buf_bytes = null;
			private byte []ip_header_bytes = null;
			private byte []message_bytes = null;
		}

		public delegate void PacketArrivedEventHandler(
			Object sender, PacketArrivedEventArgs args);

		public event PacketArrivedEventHandler PacketArrival;

		protected virtual void OnPacketArrival(PacketArrivedEventArgs e) 
		{
			if (PacketArrival != null) 
			{
				PacketArrival(this, e);
			}
		}
	}
}
 
Robin Wang



More information about the Mono-devel-list mailing list