Bug #459
closedip2long (and possibly others) return bogus values on 64 bit
Added by Chris Buechler over 14 years ago. Updated over 14 years ago.
0%
Description
As described in this post.
http://forum.pfsense.org/index.php/topic,23519.msg122849.html#msg122849
Updated by Ermal Luçi over 14 years ago
One workaround for this is to use pack/unpack or use filter_validate($ip, FILTER_VALIDATE_IP)
Updated by Jim Pingle over 14 years ago
As noted by someone on the mailing list, this also affects input validation on things such as the DHCP server that just need to be checked again after fixing the core issue.
Updated by Yehuda Katz over 14 years ago
This should have been fixed in the PHP5 source as of last April (2009).
If the issue is still there, maybe a bug report to PHP is in order.
See http://bugs.php.net/47365
Updated by Yehuda Katz over 14 years ago
Sorry wrong link.
I can't find the right one now, but 32-bit will return signed int, and 64-bit will return unsigned.
There was a patch for it, but I am not sure what the status is.
Updated by Michael Welter over 14 years ago
From what I've read it this is not considered a bug from PHP's perspective since it is documented "Because PHP's integer type is signed, and many IP addresses will result in negative integers" See [[http://php.net/ip2long]]
For now I've gone through all the PHP pages on my system and wrapped ip2long calls w/ unpack('l',pack('l',ip2long(...))) but ultimately I think it would be a better idea to encapsulate all IPv4 code in an ipv4 class with address(), netbits(), netmask(), inverse(), network(), broadcast(), ipcompare(), ...
Updated by Scott Ullrich over 14 years ago
Can you provide us a patch that wraps all ip2long calls with unpack?? We can get that committed. Probably will not make sense to redo the functions until we add ipv6 support.
Updated by Jim Pingle over 14 years ago
It would probably be better to make our own ip2long function that does it right, and then change all our calls to use it instead. I don't think PHP will let you overload it though so it would involve renaming all instances of ip2long with whatever we make.
Updated by Michael Welter over 14 years ago
Sure, let me test tonight more thoroughly and I'll submit tomorrow.
Updated by Erik Fonnesbeck over 14 years ago
The issue on 64-bit is likely that all the high 32 bits are set from sign extension because it considers it negative, interfering with bitwise comparisons when one IP address being compared has those high 32 bits set, so I think ip2long($ip) & 0xFFFFFFFF
should work. If you want a function that does this, it could be something like this:
function ip2long32($ip) { return ( ip2long($ip) & 0xFFFFFFFF ); }
Updated by Erik Fonnesbeck over 14 years ago
I've also seen places where subnet masks are negated with the bitwise not operator. In these places, we may also need to use & 0xFFFFFFFF
on either the negated mask or the resulting address. Depending on the behavior of long2ip, it may also be necessary to use that bit mask to truncate certain calculated addresses to 32 bits before passing to long2ip. I think long2ip may just truncate to 32-bits on the PHP version used, but I'm not 100% sure.
Updated by Erik Fonnesbeck over 14 years ago
- Status changed from New to Feedback
I've made changes throughout the code to various things that used ip2long and long2ip that should fix it. I only changed the parts where there could be an issue and left the rest alone.
Updated by Michael Welter over 14 years ago
Thanks Erik, I'll test once it is in the nightly build.
Updated by Michael Welter over 14 years ago
Thanks again, I've verified it is now working on my 64-bit system.
Updated by Chris Buechler over 14 years ago
- Status changed from Feedback to Closed