2009-09-19 45 views
28

Tôi muốn kiểm tra qua php nếu ai đó kết nối với trang web của tôi qua IPv4 hoặc IPv6.Cách kiểm tra xem ai đó đã kết nối qua IPv6/IPv4

Địa chỉ khách hàng có thể được tìm thấy trong $_SERVER["REMOTE_ADDR"]nhưng cách kiểm tra xem đó là IPv4 hay IPv6?

+0

Cảm ơn bạn đã trả lời của bạn –

Trả lời

6

Điều gì về việc đếm số lượng '.' và/hoặc ':' trong $_SERVER["REMOTE_ADDR"]?

Nếu có nhiều hơn 0 ':' và không có biểu tượng '.' trong $_SERVER["REMOTE_ADDR"], tôi cho rằng bạn có thể xem xét người dùng của mình được kết nối qua IPv6.


giải pháp khác có thể sử dụng filter extension: có constants(xem cuối trang) mà dường như có liên quan đến IPv4 và IPv6:

FILTER_FLAG_IPV4 (số nguyên)
phép chỉ địa chỉ IPv4 trong bộ lọc "validate_ip" .

FILTER_FLAG_IPV6 (số nguyên)
Cho phép chỉ địa chỉ IPv6 trong bộ lọc "validate_ip" .

+5

Đừng cho rằng nếu có '' đó là một IPv4, IPv6 cũng có thể chứa các địa chỉ kiểu IPv4, ví dụ: 0: 0: 0: 0: 0: 127.0.0.1 – Christian

2

Địa chỉ IPv4 khớp với regex /^\d{1,3}(\.\d{1,3}){3,3}$/.

+1

có vẻ như nó thực hiện công việc. nhưng này ....đó là biểu hiện chính quy! nó có thể làm tất cả mọi thứ, nếu bạn chỉ biết làm thế nào ... –

22

Bạn có thể sử dụng này:

function ipVersion($txt) { 
    return strpos($txt, ":") === false ? 4 : 6; 
} 
+0

Như thế này tốt hơn so với regexp - nó nhanh hơn :) – bisko

+0

có ... có vẻ nhanh hơn –

+3

Trên máy chủ ngăn xếp kép (thường là triển khai) sẽ trả về _always_ '6' vì [địa chỉ IPv6 được ánh xạ IPv4] (https://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses). Để khắc phục điều này, hãy kiểm tra xem chuỗi đó có bắt đầu bằng ':: ffff:' (và bạn có thể muốn loại bỏ chuỗi đó). –

4

Kể từ mức cao nhất bình chọn câu trả lời có một vấn đề khá quan trọng, tôi sẽ chia sẻ của riêng tôi.

Điều này trả về true nếu địa chỉ có vẻ như là IPv6 được chuyển vào và giả mạo nếu địa chỉ có vẻ là IPv4 (hoặc IPv4-ánh xạ IPv6) được chuyển vào. Các địa chỉ thực tế không được xác thực thêm; sử dụng filter_var() nếu bạn cần xác thực chúng.

function is_ipv6($address) { 
    $ipv4_mapped_ipv6 = strpos($address, "::ffff:"); 
    return (strpos($address, ":") !== FALSE) && 
      ($ipv4_mapped_ipv6 === FALSE || $ipv4_mapped_ipv6 != 0); 
} 
+0

cảm ơn brah, hoạt động – Skyzer

+0

ipv4 ánh xạ địa chỉ vẫn là địa chỉ ipv4 không hợp lệ, tại sao bạn sẽ đếm nó là ipv4? –

+0

@CemKalyoncu vì từ quan điểm mạng, khi bạn có một IPv4 được ánh xạ, không có IPv6 đang sử dụng - vì vậy nếu bạn cần tra cứu DNS ngược hoặc bất kỳ thứ gì tương tự, nó sẽ phải là một IPv4. – Ale

26

Kiểm tra cho IPv4

$ip = "255.255.255.255"; 
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {  
    echo "Valid IPv4"; 
} 
else { 
    echo "Invalid IPv4"; 
} 

Kiểm tra cho IPv6

$ip = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329";  
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { 
    echo "Valid IPv6"; 
} 
else { 
    echo "Invalid IPv6"; 
} 

Để biết thêm, kiểm tra PHP chức năng filter_varslist of filters for validation.

+2

Cuối cùng, một giải pháp ** gốc ** – mate64

3

Bạn có thể sử dụng inet_pton:

<?php 

$packedIp = inet_pton($ip); 

if ($packedIp === false) { 
    // invalid IP 
} else if (isset($packedIp[4])) { 
    // IPv6 
} else { 
    // IPv4 
} 
0

Bạn có thể sử dụng để phát hiện AF_INET6 ipv6 trong PHP:

<?php 
if (defined('AF_INET6')) { 
    echo 'Yes'; 
} else { 
    echo 'No'; 
} 
?> 
Các vấn đề liên quan