//ToDo faire l'ipv6 (dans loooongtemps) public SendRawPing() { dataSize = 256; ttlValue = 12; protocolHeaderList = new ArrayList(); pingSocket = new Socket( AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp ); pingSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, ttlValue ); IPEndPoint localEndPoint = new IPEndPoint( IPAddress.Any, 0 ); pingSocket.Bind( localEndPoint ); icmpHeader = new IcmpHeader(); icmpHeader.Id = 0; icmpHeader.Sequence = 1; icmpHeader.Type = IcmpHeader.EchoRequestType; icmpHeader.Code = IcmpHeader.EchoRequestCode; protocolHeaderList.Add( icmpHeader ); pingPayload = new byte[dataSize]; for( int i = 0 ; i < pingPayload.Length ; i++ ) { pingPayload[i] = (byte)'e'; } pingPacket = icmpHeader.BuildPacket( protocolHeaderList, pingPayload ); receiveBuffer = new byte[pingPacket.Length]; }
private AsyncCallback receiveCallback; // Async callback function called when a receive completes #endregion Fields #region Constructors // this ping class can be disposed /// <summary> /// Base constructor that initializes the member variables to default values. It also /// creates the events used and initializes the async callback function. /// </summary> public RawSocketPing() { pingSocket = null; pingFamily = AddressFamily.InterNetwork; pingTtl = 8; pingPayloadLength = 8; pingSequence = 0; pingReceiveTimeout = 4000; pingOutstandingReceives = 0; destEndPoint = new IPEndPoint( IPAddress.Loopback, 0 ); protocolHeaderList = new ArrayList(); pingReceiveEvent = new ManualResetEvent( false ); pingDoneEvent = new ManualResetEvent( false ); receiveCallback = new AsyncCallback( PingReceiveCallback ); icmpHeader = null; icmpv6Header = null; icmpv6EchoRequestHeader = null; }
/// <summary> /// This routine creates an instance of the IcmpHeader class from a byte /// array that is a received IGMP packet. This is useful when a packet /// is received from the network and the header object needs to be /// constructed from those values. /// </summary> /// <param name="icmpPacket">Byte array containing the binary ICMP header</param> /// <param name="bytesCopied">Number of bytes used in header</param> /// <returns>Returns the IcmpHeader object created from the byte array</returns> public static IcmpHeader Create( byte[] icmpPacket, ref int bytesCopied ) { IcmpHeader icmpHeader = new IcmpHeader(); int offset = 0; // Make sure byte array is large enough to contain an ICMP header if( icmpPacket.Length < IcmpHeader.IcmpHeaderLength ) return null; icmpHeader.icmpType = icmpPacket[offset++]; icmpHeader.icmpCode = icmpPacket[offset++]; icmpHeader.icmpChecksum = BitConverter.ToUInt16( icmpPacket, offset ); offset += 2; icmpHeader.icmpId = BitConverter.ToUInt16( icmpPacket, offset ); offset += 2; icmpHeader.icmpSequence = BitConverter.ToUInt16( icmpPacket, offset ); bytesCopied = IcmpHeader.IcmpHeaderLength; return icmpHeader; }
/// <summary> /// This routine builds the appropriate ICMP echo packet depending on the /// protocol family requested. /// </summary> public void BuildPingPacket() { // Initialize the socket if it hasn't already been done //Console.WriteLine( "Building the ping packet..." ); //Console.WriteLine( "Initializing the socket if not done yet..." ); if( pingSocket == null ) { InitializeSocket(); } // Clear any existing headers in the list //Console.WriteLine( "Clearing any existing headers in the list using Clear()..." ); protocolHeaderList.Clear(); if( destEndPoint.AddressFamily == AddressFamily.InterNetwork ) { // Create the ICMP header and initialize the members //Console.WriteLine( "Creating the ICMP header and initialize the members..." ); icmpHeader = new IcmpHeader(); icmpHeader.Id = pingId; icmpHeader.Sequence = pingSequence; icmpHeader.Type = IcmpHeader.EchoRequestType; icmpHeader.Code = IcmpHeader.EchoRequestCode; // Build the data payload of the ICMP echo request //Console.WriteLine( "Building the data payload of the ICMP echo request..." ); pingPayload = new byte[pingPayloadLength]; for( int i = 0 ; i < pingPayload.Length ; i++ ) { pingPayload[i] = (byte)'e'; } // Add ICMP header to the list of headers //Console.WriteLine( "Adding ICMP header to the list of headers using Add()..." ); protocolHeaderList.Add( icmpHeader ); } else if( destEndPoint.AddressFamily == AddressFamily.InterNetworkV6 ) { Ipv6Header ipv6Header; // Required for pseudo header checksum IPEndPoint localInterface; byte[] localAddressBytes = new byte[28]; Console.WriteLine( "This part is for IPv6..." ); // An IPv6 header is required since the IPv6 protocol specifies that the // pseudo header checksum needs to be calculated on ICMPv6 packets which // requires the source and destination address that will appear in the // IPv6 packet. ipv6Header = new Ipv6Header(); // We definitely know the destination IPv6 address but the stack will // choose the "appropriate" local v6 interface depending on the // routing table which may be different than the address we bound // the socket to. Because of this we will call the Winsock ioctl // SIO_ROUTING_INTERFACE_QUERY which will return the local interface // for a given destination address by querying the routing table. Console.WriteLine( "Implementing the IOControl()..." ); pingSocket.IOControl( WinsockIoctl.SIO_ROUTING_INTERFACE_QUERY, SockaddrConvert.GetSockaddrBytes( destEndPoint ), localAddressBytes ); localInterface = SockaddrConvert.GetEndPoint( localAddressBytes ); // Fill out the fields of the IPv6 header used in the pseudo-header checksum calculation Console.WriteLine( "Filling out the IPv6 header fields..." ); ipv6Header.SourceAddress = localInterface.Address; ipv6Header.DestinationAddress = destEndPoint.Address; ipv6Header.NextHeader = 58; // IPPROTO_ICMP6 // Initialize the ICMPv6 header Console.WriteLine( "Initializing the ICMPv6 header..." ); icmpv6Header = new Icmpv6Header( ipv6Header ); icmpv6Header.Type = Icmpv6Header.Icmpv6EchoRequestType; icmpv6Header.Code = Icmpv6Header.Icmpv6EchoRequestCode; // Initialize the payload Console.WriteLine( "Initializing the payload..." ); pingPayload = new byte[pingPayloadLength]; for( int i = 0 ; i < pingPayload.Length ; i++ ) { pingPayload[i] = (byte)'e'; } // Create the ICMPv6 echo request header Console.WriteLine( "Creating the ICMPv6 echo request header..." ); icmpv6EchoRequestHeader = new Icmpv6EchoRequest(); icmpv6EchoRequestHeader.Id = pingId; // Add the headers to the protocol header list Console.WriteLine( "Adding the headers to the protocol header list..." ); protocolHeaderList.Add( icmpv6Header ); protocolHeaderList.Add( icmpv6EchoRequestHeader ); } }