| File: src\runtime\src\libraries\Common\src\System\Net\SocketAddressPal.Unix.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Ping\src\System.Net.Ping.csproj (System.Net.Ping) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; namespace System.Net { internal static class SocketAddressPal { public static readonly int IPv4AddressSize; public static readonly int IPv6AddressSize; public static readonly int UdsAddressSize; public static readonly int MaxAddressSize; #pragma warning disable CA1810 static unsafe SocketAddressPal() { int ipv4 = 0; int ipv6 = 0; int uds = 0; int max = 0; Interop.Error err = Interop.Sys.GetSocketAddressSizes(&ipv4, &ipv6, &uds, &max); Debug.Assert(err == Interop.Error.SUCCESS, $"Unexpected err: {err}"); Debug.Assert(ipv4 > 0); Debug.Assert(ipv6 > 0); Debug.Assert(uds > 0); Debug.Assert(max >= ipv4 && max >= ipv6 && max >= uds); IPv4AddressSize = ipv4; IPv6AddressSize = ipv6; UdsAddressSize = uds; MaxAddressSize = max; } #pragma warning restore CA1810 private static void ThrowOnFailure(Interop.Error err) { switch (err) { case Interop.Error.SUCCESS: return; case Interop.Error.EFAULT: // The buffer was either null or too small. throw new IndexOutOfRangeException(); case Interop.Error.EAFNOSUPPORT: // There was no appropriate mapping from the platform address family. throw new PlatformNotSupportedException(); default: Debug.Fail("Unexpected failure in GetAddressFamily"); throw new PlatformNotSupportedException(); } } public static unsafe AddressFamily GetAddressFamily(ReadOnlySpan<byte> buffer) { AddressFamily family; Interop.Error err; fixed (byte* rawAddress = buffer) { err = Interop.Sys.GetAddressFamily(rawAddress, buffer.Length, (int*)&family); } ThrowOnFailure(err); return family; } public static unsafe void SetAddressFamily(Span<byte> buffer, AddressFamily family) { Interop.Error err; if (family != AddressFamily.Unknown) { fixed (byte* rawAddress = buffer) { err = Interop.Sys.SetAddressFamily(rawAddress, buffer.Length, (int)family); } ThrowOnFailure(err); } } public static unsafe ushort GetPort(ReadOnlySpan<byte> buffer) { ushort port; Interop.Error err; fixed (byte* rawAddress = buffer) { err = Interop.Sys.GetPort(rawAddress, buffer.Length, &port); } ThrowOnFailure(err); return port; } public static unsafe void SetPort(Span<byte> buffer, ushort port) { Interop.Error err; fixed (byte* rawAddress = buffer) { err = Interop.Sys.SetPort(rawAddress, buffer.Length, port); } ThrowOnFailure(err); } public static unsafe uint GetIPv4Address(ReadOnlySpan<byte> buffer) { uint ipAddress; Interop.Error err; fixed (byte* rawAddress = &MemoryMarshal.GetReference(buffer)) { err = Interop.Sys.GetIPv4Address(rawAddress, buffer.Length, &ipAddress); } ThrowOnFailure(err); return ipAddress; } public static unsafe void GetIPv6Address(ReadOnlySpan<byte> buffer, Span<byte> address, out uint scope) { uint localScope; Interop.Error err; fixed (byte* rawAddress = &MemoryMarshal.GetReference(buffer)) fixed (byte* ipAddress = &MemoryMarshal.GetReference(address)) { err = Interop.Sys.GetIPv6Address(rawAddress, buffer.Length, ipAddress, address.Length, &localScope); } ThrowOnFailure(err); scope = localScope; } public static unsafe void SetIPv4Address(Span<byte> buffer, uint address) { Interop.Error err; fixed (byte* rawAddress = buffer) { err = Interop.Sys.SetIPv4Address(rawAddress, buffer.Length, address); } ThrowOnFailure(err); } public static unsafe void SetIPv4Address(Span<byte> buffer, byte* address) { uint addr = (uint)System.Runtime.InteropServices.Marshal.ReadInt32((IntPtr)address); SetIPv4Address(buffer, addr); } public static unsafe void SetIPv6Address(Span<byte> buffer, Span<byte> address, uint scope) { fixed (byte* rawInput = &MemoryMarshal.GetReference(address)) { SetIPv6Address(buffer, rawInput, address.Length, scope); } } public static unsafe void SetIPv6Address(Span<byte> buffer, byte* address, int addressLength, uint scope) { Interop.Error err; fixed (byte* rawAddress = buffer) { err = Interop.Sys.SetIPv6Address(rawAddress, buffer.Length, address, addressLength, scope); } ThrowOnFailure(err); } public static void Clear(Span<byte> buffer) { AddressFamily family = GetAddressFamily(buffer); buffer.Clear(); // platforms where this matters (OSXLike & BSD) use uint8 for SA length buffer[0] = (byte)Math.Min(buffer.Length, 255); SetAddressFamily(buffer, family); } } }