RSE/Models/Experimental/CustomPing.cs

39 lines
1.5 KiB
C#

using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Models.Model.Backend;
namespace Models.Experimental;
public class CustomPing
{
public static IPStatus SendIcmpEchoRequestOverRawSocket(IPAddress address, int timeout)
{
SocketConfig socketConfig = new SocketConfig(new IPEndPoint(address, 0), timeout, (CustomProtocolType) 1, RawSocket.CreateSendMessageBuffer(new() {Type = 8}));
using Socket rawSocket = RawSocket.GetRawSocket(socketConfig);
int ipHeaderLength = 20;
try
{
rawSocket.SendTo(socketConfig.SendBuffer, 0, socketConfig.SendBuffer.Length, SocketFlags.None, socketConfig.EndPoint);
byte[] numArray = new byte[136];
long timestamp = Stopwatch.GetTimestamp();
// TODO: WTF ???
EndPoint lol = socketConfig.EndPoint;
while (Stopwatch.GetElapsedTime(timestamp).TotalMilliseconds < timeout)
{
int from = rawSocket.ReceiveFrom(numArray, SocketFlags.None, ref lol);
IPStatus status;
if (from - ipHeaderLength >= 8 && RawSocket.TryGetPingReply(numArray, from, ref ipHeaderLength, out status))
return status;
}
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut)
{
}
return IPStatus.TimedOut;
}
}