Tratando de conseguir Dirección IP externa de NAT con INATExternalIPAddressCallback en C #

StackOverflow https://stackoverflow.com/questions/799557

  •  18-09-2019
  •  | 
  •  

Pregunta

¿Cómo puedo obtener la dirección IP externa de un NAT usando la biblioteca de ventanas? Estoy tratando de encontrar ninguna información sobre INATExternalIPAddressCallback, pero sólo he encontrado un ejemplo en C ++ usando las interfaces no están disponibles en C #. Cualquier orientación sería muy apreciada.

-Karl

¿Fue útil?

Solución

Lo siento, eso no contesto con una API existente de Windows que utiliza el servicio UPnP, pero Migh ayudaré

También es posible usar un efecto de aturdimiento-servidor en Internet, hay muchos abiertos, cada proveedor de VoIP tiene uno. http://en.wikipedia.org/wiki/STUN http://tools.ietf.org/html/rfc3489

por ejemplo. abrir una UDP-socket, conectarse a stun.gmx.net en el puerto 3478 y enviar un Paket como esto:

using System;
using System.Net;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace xxx
{
class STUNPacket
{
    static RNGCryptoServiceProvider m_rand=new RNGCryptoServiceProvider();

    private byte[] m_requestid=new byte[16];

    public STUNPacket()
    {
        m_rand.GetBytes(m_requestid);
    }

    public byte[] CreateRequest()
    {
        byte[] packet=new byte[0x1c] {
            //Header:
            0x00,0x01,      //Art des STUN-Pakets: 0x0001=Binding Request
            0x00,0x08,      //Länge des Pakets ohne Header
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //Transkations-ID
            //Message-Attribute:
            0x00,0x03,      //Typ: Change-Request
            0x00,0x04,      //Länge: 4 Bytes
            0x00,0x00,0x00,0x00 //Weder IP, noch Port ändern
        };

        for(int i=0;i<16;i++)
            packet[i+4]=m_requestid[i];

        return packet;
    }

    public IPEndPoint ParseResponse(byte[] paket)
    {
        if (paket.Length<20)
            throw new Exception("STUN-Response zu kurz, um einen Header zu haben");
        if (paket[0]!=1||paket[1]!=1)
            throw new Exception("STUN-Reposne hat falschen Typ, muss Binding-Response sein");
        for (int i=0;i<16;i++)
            if (paket[i+4]!=m_requestid[i])
                throw new Exception("STUN-Antwort hat falsche Transkations-ID");
        int size=paket[2]*256+paket[3];
        int pos=20;
        for(;;)
        {
            if (size<4)
                throw new Exception("Verbleibende Nachricht zu kurz für weiteren Attributheader, "+
                    "Mapped-Adress-Attribut nicht gefunden");
            int attrsize=paket[pos+2]*256+paket[pos+3];
            if (pos+4+attrsize>paket.Length)
                throw new Exception("Attributheader hat Länge, die nicht mehr ins Paket passt");
            //Wenn kein Mapped-Adress-Attribut, dann überspringen
            if (paket[pos]!=0||paket[pos+1]!=1)
            {
                pos+=attrsize;
                continue;
            }
            if (attrsize<8)
                throw new Exception("Mapped-Adress-Attribut ist zu kurz");
            if (paket[pos+5]!=1)
                throw new Exception("Adreßfamilie von Mapped-Adress ist nicht IPV4");
            int port=paket[pos+6]*256+paket[pos+7];
            IPAddress adress=new IPAddress(new byte[4] { paket[pos+8],paket[pos+9],paket[pos+10],paket[pos+11] });
            return new IPEndPoint(adress,port);
        }
    }

}

}

La dirección IP devuelta por ParseResponse debe ser su dirección IP como el resto del mundo lo ve.

Nota que no será capaz de obtener su IP externa, ya sea sin la ayuda de un servidor de Internet o directamente a través de UPnP del servidor

Otros consejos

En CodeProject el siguiente artículo de Harold Aptroot describe lo que quiere hacer:

NAT transversal con UPnP en C #, sin ningún tipo de bibliotecas. http://www.codeproject.com/KB/IP/upnpnattraversal.aspx

¡Por supuesto esto sólo funciona si el router es compatible con UPnP.

a partir de MSDN - http: // MSDN. microsoft.com/en-us/library/aa365074(VS.85).aspx :

La interfaz INATExternalIPAddressCallback es implementado por la aplicación NAT con la tecnología UPnP. Proporciona un método que el sistema llama a si la dirección IP externa del equipo NAT cambios .

¿Estás tratando de obtener la dirección IP externa una vez o si desea que se le notifique si cambia. No es necesario para implementar la llamada de retorno para INATExternalIPAddressCallback si lo que desea es obtener la dirección IP externa actual

El sistema detrás del NAT no sabe que es IP "real". De hecho, en lo que se refiere al sistema operativo, tiene una IP como cualquier otro. Simplemente rutas de salida de la puerta de entrada definido y no tiene que preocuparse por los detalles. El hecho de que la IP configurada no es una dirección de difusión (10.whatever, 192.168.whatever) No importa que el sistema operativo.

La ÚNICA manera de conseguir su IP externa es consultar algún sistema externo. Puede ser que sea el router UPnP (que podría, en thoery, volver otra dirección que no sea de difusión) o podría ser algún servidor externo en el Internet (esta cosa "STUN", por ejemplo).

Si fuera yo, que acababa de alojar mi propio servicio en mi sitio web. Usted sólo puede lanzar un sencillo script php en la mayoría de cualquier sitio web PHP capaces:

<?php echo $REMOTE_ADDR; >

Esto relajarse la dirección IP del cliente. A continuación tienes que escribir el código de cliente para obtener los resultados de ese guión (bastante fácil en C #).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top