[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


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?

//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;

	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()
			len_receive_buf = 4096;
			receive_buf_bytes = new byte[len_receive_buf];
		public void CreateAndBindSocket(string IP)
			socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
			socket.Blocking = false;
			socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0));

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

		public void Shutdown()
			if(socket != null)

		private bool SetSocketOption()
			bool ret_value = true;
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;
				ret_value = false;
			return ret_value;

		public bool ErrorOccurred
				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;
					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.PacketLength =(uint)len;
				e.MessageLength =(uint)len - e.HeaderLength;

		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)
				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