Всем привет, В C# программу мне необходимо добавить пинг и трассировку. Задача стандартная, примеров в инете много, поэтому без проблем переложил c++ коды на C#. Так вот, на XP и SUSE Linux пинг и трассировка работали без проблем, а вот на Висте пинг проходит, а с трассировкой начинаются танцы с бубнами: *** Trace route for 213.180.204.8 *** Over a maximum of 30 hops: 1 * Request timed out. 2 * Request timed out. 3 * Request timed out. 4 * Request timed out. 5 * Request timed out. 6 * Request timed out. 7 31ms 0.0.0.0 8 31ms 0.0.0.0 9 31ms 0.0.0.0 10 31ms 0.0.0.0 11 и тд. хотя на других ОС она работала так *** Trace route for 213.180.204.8 *** Over a maximum of 30 hops: 1 109ms 192.168.82.13 2 0ms 10.50.1.1 3 15ms 77.222.144.5 4 15ms 80.91.178.88 5 0ms 195.35.65.88 6 31ms 213.180.208.94 7 31ms 213.180.204.8 Trace is completed. Получается пока я начинаю перебирать TTL от 1 до нужного хопа, программа не получает ни одного пакета. Но после того как я достигаю нужного хоста начинают поступать пустые пакеты до тех пор, пока я не исчерпаю все допустымые хопы. Файервол отключал - все так же, не работают также C++ коды, но как только я запускаю снифер, все начинает работать! Что за хренатень? Вот коды трассировки | Код | private string Tracert(IPAddress ipAddress, short maxHops, int nMessageSize) { StringBuilder resultStr = new StringBuilder(); int hopsTraversed = 0; string ipDest = ""; bool flagPingExist; byte ttl = 1;
//icmp header ICMPdata sendDataIcmp = new ICMPdata(nMessageSize); ushort nSequence = 1; ushort nId = (ushort)maxHops; sendDataIcmp.sendHeader.byType = 8; // ICMP_ECHO sendDataIcmp.sendHeader.byCode = 0; sendDataIcmp.sendHeader.nChecksum = 0; sendDataIcmp.sendHeader.nId = nId; sendDataIcmp.sendHeader.nSequence = (ushort)nSequence; sendDataIcmp.data = new byte[nMessageSize]; for (int i = 0; i < nMessageSize; i++) { sendDataIcmp.data[i] = 0x78; //'x' }
//ip header IPdataHeader ipHeader = new IPdataHeader(); ipHeader.ip_header_len_version = 0x45; ipHeader.ip_tos = 0; ipHeader.ip_total_length = (ushort)(sendDataIcmp.GetSize() + Marshal.SizeOf(ipHeader)); ipHeader.ip_id = (ushort)IPAddress.HostToNetworkOrder((short)nId); ipHeader.ip_frag_offset = 0; ipHeader.ip_ttl = ttl; ipHeader.ip_protocol = 1; //IPPROTO_ICMP; ipHeader.ip_checksum = 0; //define IP of my PC IPHostEntry ipMyHostEntry = Dns.GetHostEntry(Dns.GetHostName()); flagPingExist = false; foreach (IPAddress ip in ipMyHostEntry.AddressList) { if (ParseIP(ip.ToString())) { flagPingExist = true; ipHeader.ip_srcaddr = BitConverter.ToUInt32(ip.GetAddressBytes(), 0); break; } } if (!flagPingExist) { resultStr.AppendLine("<br>The socket error: Cannot define IP of this workstation."); return resultStr.ToString(); } //define dest IP ipHeader.ip_destaddr = (uint)BitConverter.ToUInt32(ipAddress.GetAddressBytes(), 0);
Socket pingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); pingSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1); while ((hopsTraversed < maxHops) && (ipAddress.ToString() != ipDest)) { ChangeTextNumberList(String.Format("Tracer route for {0} ({1} of {2})", ipAddress.ToString(), hopsTraversed + 1, maxHops)); resultStr.AppendFormat(" {0}", hopsTraversed + 1); try { IPEndPoint endPoint = new IPEndPoint(ipAddress, 0); DateTime dateBeforePing = DateTime.Now; sendDataIcmp.timeTick = (uint)(dateBeforePing.Ticks / TimeSpan.TicksPerMillisecond); ushort[] shortBufferSend = sendDataIcmp.ToUshort(); if (shortBufferSend == null) { resultStr.AppendLine("<br>The socket error: Cannot get a check sum."); pingSocket.Close(); return resultStr.ToString(); } sendDataIcmp.sendHeader.nChecksum = Checksum(ref shortBufferSend, sendDataIcmp.GetSize()); byte[] sendData = new byte[Marshal.SizeOf(ipHeader) + sendDataIcmp.GetSize()]; byte[] bytesTemp = ipHeader.ToBytes(); bytesTemp.CopyTo(sendData, 0); bytesTemp = sendDataIcmp.ToBytes(); bytesTemp.CopyTo(sendData, Marshal.SizeOf(ipHeader)); pingSocket.SendTo(sendData, endPoint); byte[] recvBuffer = new byte[1500]; EndPoint senderRemote = (EndPoint)endPoint; GetHostEntryFinished.Reset(); pingSocket.BeginReceiveFrom(recvBuffer, 0, recvBuffer.Length, SocketFlags.None, ref senderRemote, new AsyncCallback(PingCallback), pingSocket); if (!GetHostEntryFinished.WaitOne(3000, false)) { resultStr.Append(" * Request timed out.<br>"); } else { DateTime dateAfterPing = DateTime.Now; int timePing = (int)((dateAfterPing.Ticks - dateBeforePing.Ticks) / TimeSpan.TicksPerMillisecond); //type if (recvBuffer[20] == 3) { resultStr.AppendLine("<br>The socket error: Destination unreachable."); pingSocket.Close(); return resultStr.ToString(); } resultStr.AppendFormat(" {0}ms", timePing); ipDest = String.Format("{0}.{1}.{2}.{3}", recvBuffer[12].ToString(), recvBuffer[13].ToString(), recvBuffer[14].ToString(), recvBuffer[15].ToString()); //define a name resultStr.AppendFormat(" {0}<br>", ipDest); } } catch (Exception ex) { MessageBox.Show("Socket error because " + "the following problem occured:" + Environment.NewLine + ex.Message, "Exception occured"); resultStr.AppendFormat("<br>The socket error: {0}", ex.Message); pingSocket.Close(); return resultStr.ToString(); } hopsTraversed++; sendDataIcmp.sendHeader.nSequence = ++nSequence; sendDataIcmp.sendHeader.nId = nId; ipHeader.ip_id = (ushort)IPAddress.HostToNetworkOrder((short)++nId); sendDataIcmp.sendHeader.nChecksum = 0; ipHeader.ip_ttl = ++ttl; }
if (ipAddress.ToString() == ipDest) resultStr.Append("Trace is completed."); else resultStr.Append("Trace is not completed."); pingSocket.Close(); return resultStr.ToString(); }
|
|