2012-09-15 7 views
5

Mam do czynienia z problemem z $ _SERVER ['REMOTE_ADDR'] w PHP Podaje wartość podobną do IPv6, mimo że serwer używa IPv4.

Czy ktoś może mi pomóc rozwiązać ten problem.

+0

Czy jesteś pewien, że serwer jest uruchomiony na IPv4? –

+2

Dzieje się tak dlatego, że serwer WWW jest powiązany z [::], a nie 0.0.0.0. –

Odpowiedz

15

Serwer akceptuje połączenia w gnieździe IPv6. Niektóre systemy operacyjne mogą obsługiwać zarówno IPv4, jak i IPv6 na gnieździe IPv6. Gdy tak się stanie, adres IPv6 będzie wyglądać tak: ::ffff:192.0.2.123 lub ::ffff:c000:027b, który jest tym samym adresem, ale zapisany w systemie szesnastkowym.

Jeśli zobaczysz adresy IPv6 jak 2a00:8640:1::224:36ff:feef:1d89 wtedy nasz serwer naprawdę jest osiągalny przez IPv6 :-)

Zresztą konwertować wszystko z powrotem do postaci kanonicznej można używać coś takiego:

// Known prefix 
$v4mapped_prefix_hex = '00000000000000000000ffff'; 
$v4mapped_prefix_bin = pack("H*", $v4mapped_prefix_hex); 

// Or more readable when using PHP >= 5.4 
# $v4mapped_prefix_bin = hex2bin($v4mapped_prefix_hex); 

// Parse 
$addr = $_SERVER['REMOTE_ADDR']; 
$addr_bin = inet_pton($addr); 
if($addr_bin === FALSE) { 
    // Unparsable? How did they connect?!? 
    die('Invalid IP address'); 
} 

// Check prefix 
if(substr($addr_bin, 0, strlen($v4mapped_prefix_bin)) == $v4mapped_prefix_bin) { 
    // Strip prefix 
    $addr_bin = substr($addr_bin, strlen($v4mapped_prefix_bin)); 
} 

// Convert back to printable address in canonical form 
$addr = inet_ntop($addr_bin); 

Używając tego kodu, kiedy wejście jedną z następujących czynności:

::ffff:192.000.002.123 
::ffff:192.0.2.123 
0000:0000:0000:0000:0000:ffff:c000:027b 
::ffff:c000:027b 
::ffff:c000:27b 
192.000.002.123 
192.0.2.123 

zawsze uzyskać Canonica l Adres IPv4 192.0.2.123 jako wynik.

i oczywiście adresów IPv6 uzyskać zwracane jako kanonicznych adresów IPv6: 2a00:8640:0001:0000:0224:36ff:feef:1d89 staje 2a00:8640:1::224:36ff:feef:1d89 itp

+0

Dzięki. Zrobię coś, żeby przefiltrować IP. – Brijesh

+0

Próbowałem dodać wszystkie swoje przykłady do mojego skryptu testowego, i nigdy nie wykonuję stripowania prefiksu. Czy w przykładowym kodzie znajduje się zbyt wiele zer w twoim przykładzie? –

+0

Nie, wszystkie przykłady są prawidłowe. Czy możesz pokazać swój skrypt testowy? –