hybertone goip go ip

goip - Golang distingue IPv4 IPv6



gsm voip gateway (5)

La longitud de IP casi siempre es 16, porque la representación interna de net.IP es la misma para cualquier caso. De la documentación :

Tenga en cuenta que en esta documentación, hacer referencia a una dirección IP como una dirección IPv4 o una dirección IPv6 es una propiedad semántica de la dirección, no solo la longitud de la porción de bytes: una porción de 16 bytes puede ser una dirección IPv4.

La separación de los dos tipos depende de cómo se inicializó la IP. Al net.IPv4() el código de net.IPv4() , puede ver que se inicializa a 16 bytes, para lo cual los primeros 12 bytes se configuran con el valor de v4InV6Prefix .

// IPv4 returns the IP address (in 16-byte form) of the // IPv4 address a.b.c.d. func IPv4(a, b, c, d byte) IP { p := make(IP, IPv6len) copy(p, v4InV6Prefix) p[12] = a p[13] = b p[14] = c p[15] = d return p }

Donde v4InV6Prefix se define como:

var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}

Si desea una diferenciación confiable, mire cómo la fuente de net.IP.To4 maneja:

// To4 converts the IPv4 address ip to a 4-byte representation. // If ip is not an IPv4 address, To4 returns nil. func (ip IP) To4() IP { if len(ip) == IPv4len { return ip } if len(ip) == IPv6len && isZeros(ip[0:10]) && ip[10] == 0xff && ip[11] == 0xff { return ip[12:16] } return nil }

isZeros no se exporta, por lo que tendrá que copiar ese código localmente. Luego, simplemente puede hacer lo mismo que el anterior para determinar si tiene IPv4 o IPv6.

Para un programa en el que estoy trabajando, tengo que verificar si una IP (la IP que me conecta a Internet) es pública o privada. Para eso, necesito distinguir si una IP es IPv4 o IPv6.

Quería comprobarlo por la longitud del IP:

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

Bueno, mi IP es 192.168.2.100, entonces IPv4, pero len (ip) me dice que la longitud es 16, que sería IPv6. Cual es mi error ¿Existe algún otro método para distinguir entre IPv4 e IPv6 que funciona siempre?


La respuesta aceptada por ( ip.To4() != nil ) resuelve la pregunta. Sin embargo, ha habido algunos comentarios y otras respuestas que verifican si la representación es IPv4 o IPv6 y no siempre son precisas:

NOTA : Un par de listas de notaciones válidas de IPv4 e IPv6 respectivamente siguen. Cada entrada representa una variación sobre la primera básica. Las variaciones pueden combinarse como se desee, pero por razones de espacio no se enumera ninguna combinación de variaciones excepto para eliminar la ambigüedad.

Notaciones válidas de IPv4:

  • "192.168.0.1" : básico
  • "192.168.0.1:80" : con información del puerto

Notaciones válidas de IPv6:

  • "::FFFF:C0A8:1" : básico
  • "::FFFF:C0A8:0001" : ceros "::FFFF:C0A8:0001"
  • "0000:0000:0000:0000:0000:FFFF:C0A8:1" : doble colon expandido
  • "::FFFF:C0A8:1%1" : con información de zona
  • "::FFFF:192.168.0.1" : literal de IPv4
  • "[::FFFF:C0A8:1]:80" : con información del puerto
  • "[::FFFF:C0A8:1%1]:80" : con información de zona y puerto

Todos estos casos (tanto las listas de IPv4 como las de IPv6) serían consideradas direcciones IPv4 por el paquete de net . La variación literal de IPv4 de la lista de IPv6 sería considerada como IPv4 por github.com/asaskevich/govalidator/pull/100 .

La forma más fácil de verificar si es una dirección IPv4 o IPv6 sería la siguiente:

import strings func IsIPv4(address string) bool { return strings.Count(address, ":") < 2 } func IsIPv6(address string) bool { return strings.Count(address, ":") >= 2 }


La respuesta de Jim es correcta, pero bastante complicada. Simplemente verificaría ip.To4() != nil . Dado que la documentación dice "si ip no es una dirección IPv4, To4 devuelve nil" esta condición debería devolver true si y solo si la dirección es una dirección IPv4.


Usaría .To4 (), .To16 (), del paquete net, para encontrar si es una dirección IPv4 o IPv6. Revisa la publicación del blog . Revisa la última sección del blog, por ejemplo, que pueda ayudarte.


govalidator verifica la presencia de : en la cadena.

func IsIPv6(str string) bool { ip := net.ParseIP(str) return ip != nil && strings.Contains(str, ":") }