/// <summary> /// This method will return the size of the buffer and assign /// the contents of the ICMP packet to the buffer during the /// calculation. /// </summary> /// <param name="packet">ICMP Packet to work with</param> /// <param name="buffer">The buffer that will contain the information</param> /// <returns>The size of the buffer</returns> private static int Serialise(IcmpPacket packet, byte[] buffer) { int index = 0; int packLen = packet.RetrieveData().Length; byte[] type = new byte[1]; type[0] = packet.Type; byte[] code = new byte[1]; code[0] = packet.SubCode; byte[] chkSum = BitConverter.GetBytes(packet.Checksum); byte[] id = BitConverter.GetBytes(packet.Identifier); byte[] seq = BitConverter.GetBytes(packet.SequenceNumber); Array.Copy( type, 0, buffer, index++, 1); Array.Copy( code, 0, buffer, index++, 1); Array.Copy( chkSum, 0, buffer, index, chkSum.Length); index += chkSum.Length; Array.Copy( id, 0, buffer, index, id.Length); index += id.Length; Array.Copy( seq, 0, buffer, index, seq.Length); index += seq.Length; Array.Copy( packet.RetrieveData(), 0, buffer, index, packLen); index += packLen; if ( index != packet.Size ) index = -1; return index; }
/// <summary> /// Workout the checksum of the packet and assign it. /// </summary> /// <param name="packet">The packet to workout the checksum on.</param> /// <param name="buffer">The buffer which contain the complete echo packet</param> private static void ConvertBuffer(IcmpPacket packet, byte[] buffer) { // Get half size of the packet double halfLen = Convert.ToDouble((packet.Size / 2)); double temp = Math.Ceiling(halfLen / 2); int bufLen = Convert.ToInt32(temp); // Create the byte array UInt16[] chkSum = new UInt16[bufLen]; int bufIdx = 0; for (int i = 0; i < bufLen; i++) { chkSum[i] = BitConverter.ToUInt16(buffer, bufIdx); bufIdx += 2; } // Call method to return packet.Checksum = CalculateChecksum(chkSum); // Now we have the check sum Serialise again the the buffer if (Serialise(packet, buffer) == -1) { throw new InvalidOperationException(SmartResourceManager.GetString("SD_002", "Workshare.Common.Exceptions.Resources", Assembly.GetAssembly(typeof(SmartDetect)), SmartResourceManager.CurrentCulture)); } }
/// <summary> /// Ping the computer name specified /// </summary> /// <param name="computerName">The computer to locate</param> /// <returns>True if succesful</returns> /// <remarks>IMPORTANT this code will throw a SocketException if the user does not belong to the local /// admin group. This is due to the fact that Microsoft OS Windows 2000, XP, Windows Server 2003 do not /// allow raw sockets to be created if the user does not belong to the local administrator group.</remarks> /// <exception cref="ArgumentNullException">The computerName is empty</exception> /// <exception cref="ArgumentException">Cannot resolve the computer name</exception> /// <exception cref="SecurityException">Cannot access computer</exception> /// <exception cref="InvalidOperationException">Cannot create the ICMP packet information</exception> /// <exception cref="SocketException">If user does not belong to the local admin group</exception> public static bool Ping(string computerName) { bool res = false; // Set the destination of the echo packet // and the sender address information IPHostEntry dest = GetHost(computerName); IPHostEntry sender = GetHost("."); // Create the ICMP Packet Buffer int packetSize = 0; IcmpPacket packet = new IcmpPacket(); // Work out the buffer itself packetSize = packet.RetrieveData().Length + 8; byte[] icmpBuffer = new byte[packetSize]; int index = Serialise(packet, icmpBuffer); if (index == -1) { throw new InvalidOperationException(SmartResourceManager.GetString("SD_002", "Workshare.Common.Exceptions.Resources", Assembly.GetAssembly(typeof(SmartDetect)), SmartResourceManager.CurrentCulture)); } ConvertBuffer(packet, icmpBuffer); res = SendData(sender, dest, icmpBuffer); return res; }