phpBB2 IPv6 database/code compatibility hack
Carmen Sandiego on Saturday, 24 September 2005 20:47:55
Hey there,
I run a reasonably large forum community, making use of phpBB 2. I found IPv6 support to be lacking in phpBB's database/code, resulting in corrupted output from the encode_ip and decode_ip functions whenever the subject was an IPv6 user.
The reason is that phpBB assumes that all addresses are IPv4, and hence it encodes all addresses into hexadecimal form, subsequently writing them to a VARCHAR(8) field in the database. :)
I worked around this issue by enlarging the fields that store IP's to VARHCAR(39) (it's not pretty, I know), and adding a check to the IP encoding/decoding functions. If the encoded IP is equal or less than 8 characters long, phpBB will assume it's a hex-encoded IPv4 address and decode appropriately. If it is any larger, it will assume it is a plaintext IPv6 address (including semicolons) and not decode anything, just return the value.
You can find the hack instructions here: http://io.nocarrier.nl/pub/phpbb2-ipv6hack.bz2
There's got to be a more efficient way to store IPv6 addresses (encoded or not) into a database though... the field length increase from 8 to 39 is almost absurd. I'd greatly appreciate any input on this matter!
Thanks,
Chris
phpBB2 IPv6 database/code compatibility hack
Shadow Hawkins on Wednesday, 02 November 2005 22:36:23
hmmm...in theory you could do a VARCHAR(32), omitting the colons, because there is a unique translation of a :: into a string of zeroes (see Bieringer on this). So, for example, ::1 would be 00000000000000000000000000000001 and 2001:f30c:42:101::3fe:2 would be 2002f30c004201010000000003fe0002
Seems to me you could use a 16-byte number (rather than a 32-byte VARCHAR) to store these. That would be the minimum storage. (Also seems to me that it's far better to use 32 bytes to achieve clarity.)
And you could uniquely specify all those IPv4 addresses using the dedicated 2002: prefix -- for example, 192.254.32.1 becomes 2002c0fe200100000000000000000000, which extracts as 2002:c0fe:2001::, but that would hopelessly confuse people still living in the IPv4-only world...or maybe not. You should probably set up your extraction program to look for the 2002 prefix and translate the next four octets into a dotted-decimal IPv4 address in any event.
phpBB2 IPv6 database/code compatibility hack
Shadow Hawkins on Wednesday, 08 June 2011 17:40:53
Hello Chris,
sadly your hack instructions are not available for download :(
Can you please upload them again?
Thanks,
Andreas
phpBB2 IPv6 database/code compatibility hack
Shadow Hawkins on Sunday, 12 June 2011 14:31:02
I found the solution: function encode_ip($dotquad_ip)
{
if (substr_count($dotquad_ip,":") > 0 && substr_count($dotquad_ip,".") == 0){
// ipv6 - "::1" => "0000000000000000000000000001"(hex)
// unconpress - "::1" => "0:0:0:0:0:0:0:1"
if(strstr($dotquad_ip,"::" )){
$e = explode(":", $dotquad_ip);
$s = 8-sizeof($e)+1;
foreach($e as $key=>$val){
if ($val == ""){
for($i==0;$i<=$s;$i++)
$newip[] = 0;
} else {
$newip[] = $val;
}
}
$dotquad_ip = implode(":", $newip);
}
$ip_sep = explode(':', $dotquad_ip);
return sprintf('%04x%04x%04x%04x%04x%04x%04x%04x', hexdec($ip_sep[0]), hexdec($ip_sep[1]), hexdec($ip_sep[2]), hexdec($ip_sep[3]),hexdec($ip_sep[4]), hexdec($ip_sep[5]), hexdec($ip_sep[6]), hexdec($ip_sep[7]));
} else {
// ipv4 - "127.0.0.1" => "7F000001"
$ip_sep = explode('.', $dotquad_ip);
return sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}
}
function decode_ip($int_ip)
{
if ( strlen($int_ip) == 32){
// ipv6 - "..." => ""
$hexipbang = chunk_split($int_ip, 4, ':');
/*$hexipbang = explode(':', chunk_split($int_ip, 4, ':'));
//compress
if(!strstr($hexipbang,"::" )){
$e = explode(":", $hexipbang);
$zeros = array(0);
$result = array_intersect ($e, $zeros );
if (sizeof($result) >= 6){
if ($e[0]==0) {$newip[] = "";}
foreach($e as $key=>$val){
if ($val !=="0"){
$newip[] = $val;
}
}
$hexipbang = implode("::", $newip);
}
}else{
$hexipbang = implode(":", $hexipbang);
}
*/return $hexipbang;
} else {
// ipv4 - "7F000001" => "127.0.0.1"
$hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
return hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
}
Posting is only allowed when you are logged in. |