Essayer d'obtenir IPAddress externe de NAT avec INATExternalIPAddressCallback en C #

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

  •  18-09-2019
  •  | 
  •  

Question

Comment puis-je obtenir l'adresse IP externe d'un NAT en utilisant la bibliothèque Windows? Je suis en train de trouver des informations sur INATExternalIPAddressCallback, mais ont seulement trouvé un exemple en C ++ en utilisant des interfaces non disponibles pour C #. Toute orientation serait très apprécié.

-Karl

Était-ce utile?

La solution

Désolé, je ne réponds pas avec une API existante à partir de Windows qui utilise le service UPNP, mais il MIGH vous aider

Vous pouvez également utiliser un STUN-serveur sur Internet, il y a beaucoup de ceux ouverts, chaque fournisseur de VOIP a un. http://en.wikipedia.org/wiki/STUN http://tools.ietf.org/html/rfc3489

par exemple. ouvrir un socket UDP, connectez-vous stun.gmx.net sur le port 3478 et envoyer un paket comme ceci:

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);
        }
    }

}

}

L'adresse IP renvoyée par parseResponse devrait être votre adresse IP comme le monde extérieur voit.

Notez que ne sera pas en mesure d'obtenir votre adresse IP externe sans que ni l'aide d'un serveur Internet ou directement via upnp de votre serveur

Autres conseils

CodeProject l'article suivant par harold Aptroot décrit ce que vous voulez faire:

NAT traversal avec UPnP en C #, sans bibliothèques. http://www.codeproject.com/KB/IP/upnpnattraversal.aspx

Bien sûr cela ne fonctionne que si votre routeur prend en charge UPnP.

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

L'interface INATExternalIPAddressCallback est mis en œuvre par l'application NAT avec la technologie UPnP. Il fournit une méthode que le système appelle si l'adresse IP externe de l'ordinateur NAT modifications .

Êtes-vous essayer d'obtenir l'adresse IP externe une fois ou vous souhaitez être averti si elle change. Vous n'avez pas besoin de mettre en œuvre la fonction de rappel pour INATExternalIPAddressCallback si vous voulez juste pour obtenir l'adresse IP externe actuelle

Le système derrière le NAT ne sait pas qu'il est IP « réel ». En fait, dans la mesure où le système d'exploitation est concerné, il a une adresse IP comme les autres. Il suffit de voies de sortie à la passerelle définie et n'a pas à se soucier des détails. Le fait que l'adresse IP configurée est pas une adresse de diffusion (10.whatever, 192.168.whatever) n'a pas d'importance à l'OS.

La seule façon d'obtenir votre adresse IP externe est d'interroger un système externe. Ce pourrait être votre routeur UPnP (qui pourrait, dans thoery, revenir encore une autre adresse non-diffusion) ou il pourrait être un serveur externe sur Internet (cette chose « STUN », par exemple).

Si elle était moi, je venais héberger mon propre service sur mon site. Vous pouvez simplement jeter un simple script php sur la plupart un site Web PHP capable:

<?php echo $REMOTE_ADDR; >

Cela relaxe l'adresse IP du client. Ensuite, vous devez écrire le code client pour saisir les résultats de ce script (assez facile en C #).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top