b415e4835aea9d3670b55063f8acc8aa24cad71b
Jeremy D Importing SMF IPv6 mod

Jeremy D authored 12 years ago

1) <?xml version="1.0"?>
2) <!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification">
3) <modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/">
4) 
5) 	<id>sleepy:ipv6_support</id>
6) 
7) 	<version>1.0</version>
8) 
9) 	<file name="$sourcedir/ManageSearchEngines.php">
10) 
11) 		<operation>
12) 
13) 			<search position="after"><![CDATA[	foreach ($spider_data as $spider)
14) 	{
15) 		// User agent is easy.
16) ]]></search>
17) 
18) 			<add><![CDATA[	// IPv6!!! I have no idea why we do a preg match when we already validated the ip in QueryString. I wont do it.
19) 	if (empty($ip_parts) && strpos($_SERVER['REMOTE_ADDR'], ':') !== false)
20) 		$ip_parts = smf_ipv6_to_ints($_SERVER['REMOTE_ADDR']);
21) 
22) ]]></add>
23) 
24) 		</operation>
25) 
26) 	</file>
27) 
28) 	<file name="$sourcedir/ManageBans.php">
29) 
30) 		<operation>
31) 
32) 			<search position="after"><![CDATA[		);
33) 
34) 		// Preset all values that are required.
35) ]]></search>
36) 
37) 			<add><![CDATA[			'is_ipv6' => 0,
38) 			'ip_low5' => 0,
39) 			'ip_high5' => 0,
40) 			'ip_low6' => 0,
41) 			'ip_high6' => 0,
42) 			'ip_low7' => 0,
43) 			'ip_high7' => 0,
44) 			'ip_low8' => 0,
45) 			'ip_high8' => 0,
46) ]]></add>
47) 
48) 		</operation>
49) 
50) 		<operation>
51) 
52) 			<search position="after"><![CDATA[			);
53) 		}
54) 		else
55) ]]></search>
56) 
57) 			<add><![CDATA[				'is_ipv6' => 'int',
58) 				'ip_low5' => 'int',
59) 				'ip_high5' => 'int',
60) 				'ip_low6' => 'int',
61) 				'ip_high6' => 'int',
62) 				'ip_low7' => 'int',
63) 				'ip_high7' => 'int',
64) 				'ip_low8' => 'int',
65) 				'ip_high8' => 'int',
66) ]]></add>
67) 
68) 		</operation>
69) 
70) 		<operation>
71) 
72) 			<search position="replace"><![CDATA[				ip_low4 = {int:ip_low4}, ip_high4 = {int:ip_high4}';
73) ]]></search>
74) 
75) 			<add><![CDATA[				ip_low4 = {int:ip_low4}, ip_high4 = {int:ip_high4},
76) 				is_ipv6 = {int:is_ipv6},
77) 				ip_low5 = {int:ip_low5}, ip_high5 = {int:ip_high5},
78) 				ip_low6 = {int:ip_low6}, ip_high6 = {int:ip_high6},
79) 				ip_low7 = {int:ip_low7}, ip_high7 = {int:ip_high7},
80) 				ip_low8 = {int:ip_low8}, ip_high8 = {int:ip_high8}';
81) ]]></add>
82) 
83) 		</operation>
84) 
85) 		<operation>
86) 
87) 			<search position="after"><![CDATA[			$modlogInfo['ip_range'] = $_POST['ip'];
88) 		}
89) 		elseif ($_POST['bantype'] == 'hostname_ban')
90) ]]></search>
91) 
92) 			<add><![CDATA[			if (strpos($ip, ':') !== false)
93) 				$values['is_ipv6'] = 1;
94) 
95) ]]></add>
96) 
97) 		</operation>
98) 
99) 		<operation>
100) 
101) 			<search position="after"><![CDATA[					);
102) 
103) 					$ban_logs[] = array(
104) ]]></search>
105) 
106) 			<add><![CDATA[						!empty($ip_parts[4]['low']) ? 1 : 0,
107) 						$ip_parts[4]['low'],
108) 						$ip_parts[4]['high'],
109) 						$ip_parts[5]['low'],
110) 						$ip_parts[5]['high'],
111) 						$ip_parts[6]['low'],
112) 						$ip_parts[6]['high'],
113) 						$ip_parts[7]['low'],
114) 						$ip_parts[7]['high'],
115) ]]></add>
116) 
117) 		</operation>
118) 
119) 		<operation>
120) 
121) 			<search position="after"><![CDATA[					);
122) 					$ban_logs[] = array(
123) 						'hostname' => $_POST['hostname'],
124) ]]></search>
125) 
126) 			<add><![CDATA[						0, 0, 0, 0, 0, 0, 0, 0, 0,
127) ]]></add>
128) 
129) 		</operation>
130) 
131) 		<operation>
132) 
133) 			<search position="after"><![CDATA[					);
134) 					$ban_logs[] = array(
135) 						'email' => $_POST['email'],
136) ]]></search>
137) 
138) 			<add><![CDATA[						0, 0, 0, 0, 0, 0, 0, 0, 0,
139) ]]></add>
140) 
141) 		</operation>
142) 
143) 		<operation>
144) 
145) 			<search position="after"><![CDATA[					);
146) 					$ban_logs[] = array(
147) 						'member' => $_POST['bannedUser'],
148) ]]></search>
149) 
150) 			<add><![CDATA[						0, 0, 0, 0, 0, 0, 0, 0, 0,
151) ]]></add>
152) 
153) 		</operation>
154) 
155) 		<operation>
156) 
157) 			<search position="replace"><![CDATA[						if (count($ip_parts) != 4)
158) ]]></search>
159) 
160) 			<add><![CDATA[						if (count($ip_parts) != 4 || count($ip_parts) != 8)
161) ]]></add>
162) 
163) 		</operation>
164) 
165) 		<operation>
166) 
167) 			<search position="after"><![CDATA[						);
168) 						$ban_logs[] = array(
169) 							'ip_range' => $ip,
170) ]]></search>
171) 
172) 			<add><![CDATA[							!empty($ip_parts[4]['low']) ? 1 : 0,
173) 							$ip_parts[4]['low'],
174) 							$ip_parts[4]['high'],
175) 							$ip_parts[5]['low'],
176) 							$ip_parts[5]['high'],
177) 							$ip_parts[6]['low'],
178) 							$ip_parts[6]['high'],
179) 							$ip_parts[7]['low'],
180) 							$ip_parts[7]['high'],
181) ]]></add>
182) 
183) 		</operation>
184) 
185) 		<operation>
186) 
187) 			<search position="after"><![CDATA[					),
188) 					$ban_triggers,
189) 					array('id_ban')
190) ]]></search>
191) 
192) 			<add><![CDATA[						'is_ipv6' => 'int', 'ip_low5' => 'int', 'ip_high5' => 'int', 'ip_low6' => 'int', 'ip_high6' => 'int', 'ip_low7' => 'int', 'ip_high7' => 'int', 'ip_low8' => 'int', 'ip_high8' => 'int',
193) ]]></add>
194) 
195) 		</operation>
196) 
197) 		<operation>
198) 
199) 			<search position="after"><![CDATA[				bg.id_ban_group, bg.name, bg.ban_time, bg.expire_time, bg.reason, bg.notes, bg.cannot_access, bg.cannot_register, bg.cannot_login, bg.cannot_post,
200) 				IFNULL(mem.id_member, 0) AS id_member, mem.member_name, mem.real_name
201) 			FROM {db_prefix}ban_groups AS bg
202) ]]></search>
203) 
204) 			<add><![CDATA[				bi.is_ipv6, bi.ip_low5, bi.ip_high5, bi.ip_low6, bi.ip_high6, bi.ip_low7, bi.ip_high7, bi.ip_low8, bi.ip_high8,
205) ]]></add>
206) 
207) 		</operation>
208) 
209) 		<operation>
210) 
211) 			<search position="replace"><![CDATA[					$context['ban_items'][$row['id_ban']]['ip'] = range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4']));
212) ]]></search>
213) 
214) 			<add><![CDATA[					$context['ban_items'][$row['id_ban']]['ip'] = range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4'] ,$row['ip_low5'], $row['ip_low6'], $row['ip_low7'], $row['ip_low8']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'], $row['ip_high5'], $row['ip_high6'], $row['ip_high7'], $row['ip_high8']));
215) ]]></add>
216) 
217) 		</operation>
218) 
219) 		<operation>
220) 
221) 			<search position="after"><![CDATA[				mem.member_name, mem.real_name
222) 			FROM {db_prefix}ban_items AS bi
223) 				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = bi.id_member)
224) ]]></search>
225) 
226) 			<add><![CDATA[				bi.is_ipv6, bi.ip_low5, bi.ip_high5, bi.ip_low6, bi.ip_high6, bi.ip_low7, bi.ip_high7, bi.ip_low8, bi.ip_high8,
227) ]]></add>
228) 
229) 		</operation>
230) 
231) 		<operation>
232) 
233) 			<search position="replace"><![CDATA[				'value' => empty($row['ip_low1']) ? '' : range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'])),
234) ]]></search>
235) 
236) 			<add><![CDATA[				'value' => empty($row['ip_low1']) ? '' : range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4'], $row['ip_low5'], $row['ip_low6'], $row['ip_low7'], $row['ip_low8']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'], $row['ip_high5'], $row['ip_high6'], $row['ip_high7'], $row['ip_high8'])),
237) ]]></add>
238) 
239) 		</operation>
240) 
241) 		<operation>
242) 
243) 			<search position="after"><![CDATA[	if (count($low) != 4 || count($high) != 4)
244) 		return '';
245) 
246) ]]></search>
247) 
248) 			<add><![CDATA[	// IPv6 check.
249) 	if (!empty($low[5]))
250) 		return range2ip_ipv6($low, $high);
251) 
252) ]]></add>
253) 
254) 		</operation>
255) 
256) 		<operation>
257) 
258) 			<search position="after"><![CDATA[function checkExistingTriggerIP($ip_array, $fullip = '')
259) {
260) 	global $smcFunc, $scripturl;
261) 
262) ]]></search>
263) 
264) 			<add><![CDATA[function range2ip_ipv6($low, $high)
265) {
266) 	if (count($low) != 8 || count($high) != 8)
267) 		return '';
268) 
269) 	$ip = array();
270) 	for ($i = 0; $i < 8; $i++)
271) 	{
272) 		if ($low[$i] == $high[$i])
273) 			$ip[$i] = dechex($low[$i]);
274) 		elseif ($low[$i] == '0' && $high[$i] == '255')
275) 			$ip[$i] = '*';
276) 		else
277) 			$ip[$i] = dechex($low[$i]) . '-' . dechex($high[$i]);
278) 	}
279) 
280) 	return implode(':', $ip);
281) }
282) 
283) ]]></add>
284) 
285) 		</operation>
286) 
287) 		<operation>
288) 
289) 			<search position="replace"><![CDATA[	if (count($ip_array) == 4)
290) ]]></search>
291) 
292) 			<add><![CDATA[	if (count($ip_array) == 4 || count($ip_array) == 8)
293) ]]></add>
294) 
295) 		</operation>
296) 
297) 		<operation>
298) 
299) 			<search position="after"><![CDATA[		);
300) 	else
301) 		return false;
302) ]]></search>
303) 
304) 			<add><![CDATA[			'ip_low5' => $ip_array[4]['low'],
305) 			'ip_high5' => $ip_array[4]['high'],
306) 			'ip_low6' => $ip_array[5]['low'],
307) 			'ip_high6' => $ip_array[5]['high'],
308) 			'ip_low7' => $ip_array[6]['low'],
309) 			'ip_high7' => $ip_array[6]['high'],
310) 			'ip_low8' => $ip_array[7]['low'],
311) 			'ip_high8' => $ip_array[7]['high'],
312) ]]></add>
313) 
314) 		</operation>
315) 
316) 		<operation>
317) 
318) 			<search position="after"><![CDATA[		LIMIT 1',
319) 		$values
320) 	);
321) ]]></search>
322) 
323) 			<add><![CDATA[			AND ip_low5 = {int:ip_low5} AND ip_high5 = {int:ip_high5}
324) 			AND ip_low6 = {int:ip_low6} AND ip_high6 = {int:ip_high6}
325) 			AND ip_low7 = {int:ip_low7} AND ip_high7 = {int:ip_high7}
326) 			AND ip_low8 = {int:ip_low8} AND ip_high8 = {int:ip_high8}
327) ]]></add>
328) 
329) 		</operation>
330) 
331) 	</file>
332) 
333) 	<file name="$sourcedir/QueryString.php">
334) 
335) 		<operation>
336) 
337) 			<search position="replace"><![CDATA[		$_SERVER['REMOTE_ADDR'] = 'unknown';
338) ]]></search>
339) 
340) 			<add><![CDATA[	{
341) 		// !! ADDED
342) 		// Wait, maybe its IPv6? This is not pretty.
343) 		if (preg_match('~^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$~', $_SERVER['REMOTE_ADDR']) === 0)
344) 			$_SERVER['REMOTE_ADDR'] = 'unknown';
345) 	}
346) ]]></add>
347) 
348) 		</operation>
349) 
350) 		<operation>
351) 
352) 			<search position="replace"><![CDATA[	if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) != 0))
353) ]]></search>
354) 
355) 			<add><![CDATA[	if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) != 0))
356) ]]></add>
357) 
358) 		</operation>
359) 
360) 		<operation>
361) 
362) 			<search position="replace"><![CDATA[	if (!empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) != 0))
363) ]]></search>
364) 
365) 			<add><![CDATA[	if (!empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) != 0))
366) ]]></add>
367) 
368) 		</operation>
369) 
370) 		<operation>
371) 
372) 			<search position="replace"><![CDATA[				if (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $ip) != 0 && preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) == 0)
373) ]]></search>
374) 
375) 			<add><![CDATA[				if (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $ip) != 0 && preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) == 0)
376) ]]></add>
377) 
378) 		</operation>
379) 
380) 		<operation>
381) 
382) 			<search position="replace"><![CDATA[		elseif (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['HTTP_X_FORWARDED_FOR']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) != 0)
383) ]]></search>
384) 
385) 			<add><![CDATA[		elseif (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['HTTP_X_FORWARDED_FOR']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) != 0)
386) ]]></add>
387) 
388) 		</operation>
389) 
390) 		<operation>
391) 
392) 			<search position="replace"><![CDATA[		$_SERVER['BAN_CHECK_IP'] = '';
393) ]]></search>
394) 
395) 			<add><![CDATA[	{
396) 		// Wait, maybe its IPv6? This is not pretty.
397) 		if (preg_match('~^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$~', $_SERVER['BAN_CHECK_IP']) === 0)
398) 			$_SERVER['BAN_CHECK_IP'] = '';
399) 	}
400) ]]></add>
401) 
402) 		</operation>
403) 
404) 		<operation>
405) 
Jeremy D Use end instead of looking...

Jeremy D authored 11 years ago

406) 			<search position="end" />
Jeremy D Importing SMF IPv6 mod

Jeremy D authored 12 years ago

407) 
408) 			<add><![CDATA[// Working with them as if they where IPv4 numbers, makes it SMF compatible.
409) function smf_ipv6_to_ints($ip)
410) {
411) 	// Expand the IP out.
412) 	$ip = explode(':', smf_ipv6_expand($ip));
413) 
414) 	$new_ip = array();
415) 	foreach ($ip as $int)
416) 		$new_ip[] = hexdec($int);
417) 
418) 	return implode($new_ip, '-');
419) }
420) 
421) 
422) /**
423)  * IPv6 Address Functions for PHP
424)  *
425)  * Functions to manipulate IPv6 addresses for PHP
426)  *
427)  * Copyright (C) 2009 Ray Patrick Soucy
428)  *
429)  * LICENSE:
430)  *
431)  * This program is free software: you can redistribute it and/or modify
432)  * it under the terms of the GNU General Public License as published by
433)  * the Free Software Foundation, either version 3 of the License, or
434)  * (at your option) any later version.
435)  *
436)  * This program is distributed in the hope that it will be useful,
437)  * but WITHOUT ANY WARRANTY; without even the implied warranty of
438)  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
439)  * GNU General Public License for more details.
440)  *
441)  * You should have received a copy of the GNU General Public License
442)  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
443)  *
444)  * @package   inet6
445)  * @author    Ray Soucy <rps@soucy.org>
446)  * @version   1.0.1
447)  * @copyright 2009 Ray Patrick Soucy 
448)  * @link      http://www.soucy.org/
449)  * @license   GNU General Public License version 3 or later
450)  * @since     File available since Release 1.0.1
451)  */
452) function smf_ipv6_expand($addr, $strict_check = true)
453) {
454) 	/* Check if there are segments missing, insert if necessary */
455) 	if (strpos($addr, '::') !== false)
456) 	{
457) 		$part = explode('::', $addr);
458) 		$part[0] = explode(':', $part[0]);
459) 		$part[1] = explode(':', $part[1]);
460) 		$missing = array();
461) 		for ($i = 0; $i < (8 - (count($part[0]) + count($part[1]))); $i++)
462) 			array_push($missing, '0000');
463) 		$missing = array_merge($part[0], $missing);
464) 		$part = array_merge($missing, $part[1]);
465) 	}
466) 	else
467) 		$part = explode(":", $addr);
468) 
469) 	/* Pad each segment until it has 4 digits */
470) 	foreach ($part as &$p)
471) 		while (strlen($p) < 4)
472) 			$p = '0' . $p;
473) 
474) 	unset($p);
475) 
476)     /* Join segments */
477) 	$result = implode(':', $part);
478) 
479) 	/* Quick check to make sure the length is as expected */ 
480) 	if (!$strict_check || strlen($result) == 39)
481) 		return $result;
482) 	else
483) 		return false;
484) }
485) 
486) ]]></add>
487) 
488) 		</operation>
489) 
490) 	</file>
491) 
492) 	<file name="$sourcedir/Security.php">
493) 
494) 		<operation>
495) 
496) 			<search position="after"><![CDATA[			// We use '255.255.255.255' for 'unknown' since it's not valid anyway.
497) 			elseif ($user_info['ip'] == 'unknown')
498) 				$ban_query[] = '(bi.ip_low1 = 255 AND bi.ip_high1 = 255
499) ]]></search>
500) 
501) 			<add><![CDATA[			// Again, the IP was validated, why use regex when we can split.
502) 			elseif (strpos($user_info[$ip_number], ':') !== false)
503) 			{
504) 				if ($ip_number == 'ip2' && $user_info['ip2'] == $user_info['ip'])
505) 					continue;
506) 
507) 				$ip_parts = array_map('hexdec', explode(':', smf_ipv6_expand($user_info[$ip_number])));
508) 
509) 				$ban_query[] = '((' . $ip_parts[0] . ' BETWEEN bi.ip_low1 AND bi.ip_high1)
510) 							AND (' . $ip_parts[1] . ' BETWEEN bi.ip_low2 AND bi.ip_high2)
511) 							AND (' . $ip_parts[2] . ' BETWEEN bi.ip_low3 AND bi.ip_high3)
512) 							AND (' . $ip_parts[3] . ' BETWEEN bi.ip_low4 AND bi.ip_high4)
513) 							AND (' . $ip_parts[4] . ' BETWEEN bi.ip_low5 AND bi.ip_high5)
514) 							AND (' . $ip_parts[5] . ' BETWEEN bi.ip_low6 AND bi.ip_high6)
515) 							AND (' . $ip_parts[6] . ' BETWEEN bi.ip_low7 AND bi.ip_high7)
516) 							AND (' . $ip_parts[7] . ' BETWEEN bi.ip_low8 AND bi.ip_high8))';
517) 
518) 				// IP was valid, maybe there's also a hostname...
519) 				if (empty($modSettings['disableHostnameLookup']))
520) 				{
521) 					$hostname = host_from_ip($user_info[$ip_number]);
522) 					if (strlen($hostname) > 0)
523) 					{
524) 						$ban_query[] = '({string:hostname} LIKE bi.hostname)';
525) 						$ban_query_vars['hostname'] = $hostname;
526) 					}
527) 				}
528) 			}
529) ]]></add>
530) 
531) 		</operation>
532) 
533) 	</file>
534) 
535) 	<file name="$sourcedir/Profile-View.php">
536) 
537) 		<operation>
538) 
539) 			<search position="replace"><![CDATA[	if (preg_match('/^\d{1,3}\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/', $context['ip']) == 0)
540) ]]></search>
541) 
542) 			<add><![CDATA[	if (preg_match('/^\d{1,3}\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/', $context['ip']) == 0 && preg_match('~^((([0-9A-Fa-f*]{1,4}:){7}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){6}:[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){5}:([0-9A-Fa-f*]{1,4}:)?[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){4}:([0-9A-Fa-f*]{1,4}:){0,2}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){3}:([0-9A-Fa-f*]{1,4}:){0,3}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){2}:([0-9A-Fa-f*]{1,4}:){0,4}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f*]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f*]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f*]{1,4}::([0-9A-Fa-f*]{1,4}:){0,5}[0-9A-Fa-f*]{1,4})|(::([0-9A-Fa-f*]{1,4}:){0,6}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){1,7}:))$~', $context['ip']) == 0)
543) ]]></add>
544) 
545) 		</operation>
546) 
547) 	</file>
548) 
549) 	<file name="$sourcedir/Subs.php">
550) 
551) 		<operation>
552) 
553) 			<search position="after"><![CDATA[	// Pretend that 'unknown' is 255.255.255.255. (since that can't be an IP anyway.)
554) 	if ($fullip == 'unknown')
555) 		$fullip = '255.255.255.255';
556) ]]></search>
557) 
558) 			<add><![CDATA[	if (strpos($fullip, ':') !== false)
559) 		return ip2range_ipv6($fullip);
560) 
561) ]]></add>
562) 
563) 		</operation>
564) 
565) 		<operation>
566) 
567) 			<search position="after"><![CDATA[	return $ip_array;
568) }
569) 
570) ]]></search>
571) 
572) 			<add><![CDATA[
573) 	// Makes it simpiler to work with.
574) 	$ip_array[5] = array('low' => 0, 'high' => 0);
575) 	$ip_array[6] = array('low' => 0, 'high' => 0);
576) 	$ip_array[7] = array('low' => 0, 'high' => 0);
577) 	$ip_array[8] = array('low' => 0, 'high' => 0);
578) 
579) ]]></add>
580) 
581) 		</operation>
582) 
583) 		<operation>
584) 
585) 			<search position="after"><![CDATA[// Lookup an IP; try shell_exec first because we can do a timeout on it.
586) function host_from_ip($ip)
587) {]]></search>
588) 
589) 			<add><![CDATA[// Convert a single IPv6 to a ranged IPv6.
590) function ip2range_ipv6($fullip)
591) {
592) 	$ip_parts = explode(':', smf_ipv6_expand($fullip, false));
593) 	$ip_array = array();
594) 
595) 	if (count($ip_parts) != 8)
596) 		return array();
597) 
598) 	for ($i = 0; $i < 8; $i++)
599) 	{
600) 		if ($ip_parts[$i] == '*')
601) 			$ip_array[$i] = array('low' => '0', 'high' => hexdec('ffff'));
602) 		elseif (preg_match('/^([0-9A-Fa-f]{1,4})\-([0-9A-Fa-f]{1,4})$/', $ip_parts[$i], $range) == 1)
603) 			$ip_array[$i] = array('low' => hexdec($range[1]), 'high' => hexdec($range[2]));
604) 		elseif (is_numeric(hexdec($ip_parts[$i])))
605) 			$ip_array[$i] = array('low' => hexdec($ip_parts[$i]), 'high' => hexdec($ip_parts[$i]));
606) 	}
607) 
608) 	return $ip_array;
609) }
610) 
611) ]]></add>
612) 
613) 		</operation>
614) 
615) 	</file>
616)