golang distinguer IPv4 IPv6
Pour un programme sur lequel je travaille, je dois vérifier si une adresse IP (l'adresse IP qui me relie à l'Internet) est public ou privé. Pour cela, j'ai besoin de distinguer si l'adresse IP IPv4 ou IPv6.
Je voulais le vérifier par la longueur de la propriété intellectuelle:
conn, err := net.Dial("udp", "8.9.10.11:2342")
if err != nil {
fmt.Println("Error", err)
}
localaddr := conn.LocalAddr()
addr, _ := net.ResolveUDPAddr("udp", localaddr.String())
ip := addr.IP
fmt.Println(ip)
fmt.Println(len(ip))
Bien, mon IP est 192.168.2.100, donc IPv4, mais len(ip) me dit que la longueur est de 16 ans qui serait IPv6.
Quelle est mon erreur? Toute autre méthode existe pas de distinguer entre l'IPv4 et l'IPv6 qui fonctionne toujours?
Vous devez vous connecter pour publier un commentaire.
jimt la réponse est correcte, mais assez compliqué. Je voudrais simplement vérifier
ip.To4() != nil
. Étant donné que la documentation dit "si l'ip n'est pas une adresse IPv4, To4 retourne nil" cette condition doit retournertrue
si et seulement si l'adresse est une adresse IPv4.::FFFF:127.0.0.1
est une IPv6 valide représentation et retourneTrue
pourIsIPv4()
quand il doit retournerFalse
.::FFFF:
est le v4InV6Prefix, donc::FFFF:127.0.0.1
est, en fait, d'un visa d'adresse IPv4 pour toutes fins utiles.La longueur de la propriété intellectuelle est presque toujours 16, parce que la représentation interne de
net.IP
est le même pour les deux cas. De la documentation:Séparant les deux types dépend de la façon dont la propriété intellectuelle a été initialisé. En regardant le code pour
net.IPv4()
, vous pouvez voir qu'il est initialisé à 16 octets, pour lesquels les 12 premiers octets sont mis à la valeur dev4InV6Prefix
.Où
v4InV6Prefix
est défini comme:Si vous voulez une distinction fiable, regardez comment la source pour
net.IP.To4
gère:isZeros
n'est pas exporté, de sorte que vous aurez à copier ce code en local. Ensuite, vous pouvez simplement faire la même chose que ci-dessus pour déterminer si vous avez IPv4 ou IPv6.govalidator vérifie la présence de
:
dans la chaîne.IsIPv4(str string) bool
méthode aussi des pauses pour"::FFFF:192.168.0.1"
donner de faux positifs.La accepté de répondre à par Evan (
ip.To4() != nil
) résout la question. Cependant, il ya eu certains commentaires et d'autres réponses que de vérifier si la représentation est IPv4 ou IPv6 et ils ne sont pas toujours précises:NOTE: UN couple de listes de valable IPv4 et IPv6 valide notations respectivement à suivre. Chaque entrée correspond à une variation au cours de la première base. Les variations peuvent être combinés, comme souhaité, mais pour des raisons d'espace pas de variation de la combinaison est à l'exception de l'élimination de l'ambiguïté.
IPv4 valide les notations:
"192.168.0.1"
: base"192.168.0.1:80"
: avec port infoIPv6 valide les notations:
"::FFFF:C0A8:1"
: base"::FFFF:C0A8:0001"
: le zéro de"0000:0000:0000:0000:0000:FFFF:C0A8:1"
: deux points élargi"::FFFF:C0A8:1%1"
: avec la zone info"::FFFF:192.168.0.1"
: IPv4 littérale"[::FFFF:C0A8:1]:80"
: avec port info"[::FFFF:C0A8:1%1]:80"
: avec la zone et le port infoTous ces cas (à la fois IPv4 et IPv6 listes) seraient considérés comme des adresses IPv4 en le
net
le paquet.Le littéral IPv4 variation de l'IPv6 liste serait considérée être IPv4 par govalidator.
La meilleure façon de vérifier si c'est une adresse IPv4 ou IPv6 serait le suivant:
Que j'allais utiliser .4(), .16() ,sur le net, pour trouver si c'est une adresse IPv4 ou IPv6.
de vérifier la post de blog. vérifiez le dernier article du blog par exemple qui pourrait vous aider.