Saltar al contenido

PHP5 calcula el rango de IPv6 a partir del prefijo cidr?

Solución:

En primer lugar: IPv6 no tiene direcciones de red ni de difusión. Puede utilizar todas las direcciones en un prefijo. Segundo: en una LAN, la longitud del prefijo es siempre (bueno, el 99.x% del tiempo) a / 64. El enrutamiento de un / 68 rompería las características de IPv6 como la configuración automática sin estado.

A continuación se muestra una implementación detallada de una calculadora de prefijos IPv6:

<?php

/*
 * This is definitely not the fastest way to do it!
 */

// An example prefix
$prefix = '2001:db8:abc:1400::/54';

// Split in address and prefix length
list($firstaddrstr, $prefixlen) = explode("https://foroayuda.es/", $prefix);

// Parse the address into a binary string
$firstaddrbin = inet_pton($firstaddrstr);

// Convert the binary string to a string with hexadecimal characters
# unpack() can be replaced with bin2hex()
# unpack() is used for symmetry with pack() below
$firstaddrhex = reset(unpack('H*', $firstaddrbin));

// Overwriting first address string to make sure notation is optimal
$firstaddrstr = inet_ntop($firstaddrbin);

// Calculate the number of 'flexible' bits
$flexbits = 128 - $prefixlen;

// Build the hexadecimal string of the last address
$lastaddrhex = $firstaddrhex;

// We start at the end of the string (which is always 32 characters long)
$pos = 31;
while ($flexbits > 0) {
  // Get the character at this position
  $orig = substr($lastaddrhex, $pos, 1);

  // Convert it to an integer
  $origval = hexdec($orig);

  // OR it with (2^flexbits)-1, with flexbits limited to 4 at a time
  $newval = $origval | (pow(2, min(4, $flexbits)) - 1);

  // Convert it back to a hexadecimal character
  $new = dechex($newval);

  // And put that character back in the string
  $lastaddrhex = substr_replace($lastaddrhex, $new, $pos, 1);

  // We processed one nibble, move to previous position
  $flexbits -= 4;
  $pos -= 1;
}

// Convert the hexadecimal string to a binary string
# Using pack() here
# Newer PHP version can use hex2bin()
$lastaddrbin = pack('H*', $lastaddrhex);

// And create an IPv6 address from the binary string
$lastaddrstr = inet_ntop($lastaddrbin);

// Report to user
echo "Prefix: $prefixn";
echo "First: $firstaddrstrn";
echo "Last: $lastaddrstrn";

?>

Debería generar:

Prefix: 2001:db8:abc:1400::/54
First: 2001:db8:abc:1400::
Last: 2001:db8:abc:17ff:ffff:ffff:ffff:ffff

Para aquellos que se topan con esta pregunta, puede hacerlo de manera más efectiva utilizando el dtr_pton y dtr_ntop funciones y dTRIP clase que se encuentra en GitHub.

También hemos notado una falta de enfoque y herramientas con IPv6 en PHP, y reunimos este artículo, http://www.highonphp.com/5-tips-for-working-with-ipv6-in-php, que puede ser de ayuda a los demás.

Fuente de función

Esto convierte una IP en una representación binaria:

/**
 * dtr_pton
 *
 * Converts a printable IP into an unpacked binary string
 *
 * @author Mike Mackintosh - [email protected]
 * @param string $ip
 * @return string $bin
 */
function dtr_pton( $ip ){

    if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){
        return current( unpack( "A4", inet_pton( $ip ) ) );
    }
    elseif(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){
        return current( unpack( "A16", inet_pton( $ip ) ) );
    }

    throw new Exception("Please supply a valid IPv4 or IPv6 address");

    return false;
}

Esto convierte una representación binaria en IP imprimible:

/**
 * dtr_ntop
 *
 * Converts an unpacked binary string into a printable IP
 *
 * @author Mike Mackintosh - [email protected]
 * @param string $str
 * @return string $ip
 */
function dtr_ntop( $str ){
    if( strlen( $str ) == 16 OR strlen( $str ) == 4 ){
        return inet_ntop( pack( "A".strlen( $str ) , $str ) );
    }

    throw new Exception( "Please provide a 4 or 16 byte string" );

    return false;
}

Ejemplos de

Utilizando el dtr_pton función que puede:

$ip = dtr_pton("fe80:1:2:3:a:bad:1dea:dad");
$mask = dtr_pton("ffff:ffff:ffff:ffff:ffff:fff0::");

Obtenga su red y transmisión:

var_dump( dtr_ntop( $ip & $mask ) );
var_dump( dtr_ntop( $ip | ~ $mask ) );

Y su salida sería:

string(18) "fe80:1:2:3:a:ba0::"
string(26) "fe80:1:2:3:a:baf:ffff:ffff"
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *