Private/Set-BgpTcpMd5.ps1

function Set-BgpTcpMd5 {
    # Linux-only: installs an RFC 2385 TCP-MD5 key via setsockopt(TCP_MD5SIG / TCP_MD5SIG_EXT) on an IPv4 socket.
    param(
        [Parameter(Mandatory)][Net.Sockets.Socket]$Socket,
        [string]$Address,
        [Parameter(Mandatory)][string]$Password
    )
    $key = [Text.Encoding]::UTF8.GetBytes($Password)
    if ($key.Length -gt 80) { throw 'TCP-MD5 password must be at most 80 bytes.' }

    # struct tcp_md5sig: sockaddr_storage[128], flags, prefixlen, keylen(u16), ifindex(i32), key[80]
    $b = [byte[]]::new(216)
    [BitConverter]::GetBytes([uint16]2).CopyTo($b, 0)   # AF_INET
    if ($Address) {
        $ip = $null
        if (-not [ipaddress]::TryParse($Address, [ref]$ip)) {
            $ip = [Net.Dns]::GetHostAddresses($Address) | Where-Object AddressFamily -eq 'InterNetwork' | Select-Object -First 1
        }
        if (-not $ip -or $ip.AddressFamily -ne 'InterNetwork') { throw "TCP-MD5 needs an IPv4 address (got '$Address')." }
        $ip.GetAddressBytes().CopyTo($b, 4)
        $opt = 14                                       # TCP_MD5SIG
    }
    else {
        $b[128] = 1                                     # TCP_MD5SIG_FLAG_PREFIX, prefixlen 0 = any peer
        $opt = 32                                       # TCP_MD5SIG_EXT
    }
    [BitConverter]::GetBytes([uint16]$key.Length).CopyTo($b, 130)
    $key.CopyTo($b, 136)
    $Socket.SetRawSocketOption(6, $opt, $b)             # SOL_TCP
}