/** * Fetches the current IP for the specified online guest * * @return XenForo_ControllerResponse_Abstract */ public function actionGuestIp() { if (!$this->_getUserModel()->canViewIps($errorPhraseKey)) { throw $this->getErrorOrNoPermissionResponseException($errorPhraseKey); } $ip = preg_replace('#[^0-9a-f]#', '', $this->_input->filterSingle('ip', XenForo_Input::STRING)); try { $ip = XenForo_Helper_Ip::convertIpBinaryToString(XenForo_Helper_Ip::convertHexToBin($ip)); } catch (Exception $e) { $ip = false; } if (!$ip) { // likely given an invalid IP return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } $viewParams = array('ip' => $ip, 'host' => XenForo_Model_Ip::getHost($ip)); return $this->responseView('XenForo_ViewPublic_Online_GuestIp', 'online_guest_ip', $viewParams); }
/** * Converts a string based IP (v4 or v6) to a 4 or 16 byte string. * This tries to identify not only 192.168.1.1 and 2001::1:2:3:4 style IPs, * but integer encoded IPv4 and already binary encoded IPs. IPv4 * embedded in IPv6 via things like ::ffff:192.168.1.1 is also detected. * * @param string|int $ip * * @return bool|string False on failure, binary data otherwise */ public static function convertIpStringToBinary($ip) { $originalIp = $ip; $ip = trim($ip); if (strpos($ip, ':') !== false) { // IPv6 if (preg_match('#:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$#', $ip, $match)) { // embedded IPv4 $long = ip2long($match[1]); if (!$long) { return false; } $hex = str_pad(dechex($long), 8, '0', STR_PAD_LEFT); $v4chunks = str_split($hex, 4); $ip = str_replace($match[0], ":{$v4chunks['0']}:{$v4chunks['1']}", $ip); } if (strpos($ip, '::') !== false) { if (substr_count($ip, '::') > 1) { // ambiguous return false; } $delims = substr_count($ip, ':'); if ($delims > 7) { return false; } $ip = str_replace('::', str_repeat(':0', 8 - $delims) . ':', $ip); if ($ip[0] == ':') { $ip = '0' . $ip; } } $ip = strtolower($ip); $parts = explode(':', $ip); if (count($parts) != 8) { return false; } foreach ($parts as &$part) { $len = strlen($part); if ($len > 4 || preg_match('/[^0-9a-f]/', $part)) { return false; } if ($len < 4) { $part = str_repeat('0', 4 - $len) . $part; } } $hex = implode('', $parts); if (strlen($hex) != 32) { return false; } return XenForo_Helper_Ip::convertHexToBin($hex); } else { if (strpos($ip, '.')) { // IPv4 if (!preg_match('#(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})#', $ip, $match)) { return false; } $long = ip2long($match[1]); if (!$long) { return false; } return XenForo_Helper_Ip::convertHexToBin(str_pad(dechex($long), 8, '0', STR_PAD_LEFT)); } else { if (strlen($ip) == 4 || strlen($ip) == 16) { // already binary encoded return $ip; } else { if (is_numeric($originalIp) && $originalIp < pow(2, 32)) { // IPv4 as integer return XenForo_Helper_Ip::convertHexToBin(str_pad(dechex($originalIp), 8, '0', STR_PAD_LEFT)); } else { return false; } } } } }