Project

General

Profile

Download (34.8 KB) Statistics
| Branch: | Tag: | Revision:
1 17623ab5 Bill Marquette
<?php
2
/*
3 cdcea13f Seth Mos
  Copyright (C) 2008 Bill Marquette, Seth Mos
4 02a8dab0 ccesario
  Copyright (C) 2010 Ermal Luçi
5 17623ab5 Bill Marquette
  All rights reserved.
6
7
  Redistribution and use in source and binary forms, with or without
8
  modification, are permitted provided that the following conditions are met:
9
10 c1191d5b Ermal
  1. Redistributions of source code must retain the above copyright notice,
11 17623ab5 Bill Marquette
  this list of conditions and the following disclaimer.
12
13
  2. Redistributions in binary form must reproduce the above copyright
14
  notice, this list of conditions and the following disclaimer in the
15
  documentation and/or other materials provided with the distribution.
16
17
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19
  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20
  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
  POSSIBILITY OF SUCH DAMAGE.
27
28 bf8c7971 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/route	/usr/local/sbin/apinger
29 523855b0 Scott Ullrich
	pfSense_MODULE:	routing
30
31 c1191d5b Ermal
 */
32 c5e53ee6 jim-p
require_once("config.inc");
33 17623ab5 Bill Marquette
34 14661668 Phil Davis
/* Returns an array of default values used for apinger.conf */
35
function return_apinger_defaults() {
36
	return array(
37
		"latencylow" => "200",
38
		"latencyhigh" => "500",
39
		"losslow" => "10",
40
		"losshigh" => "20",
41
		"interval" => "1",
42 3c6787ed N0YB
		"down" => "10",
43
		"avg_delay_samples" => "10",
44
		"avg_loss_samples" => "50",
45
		"avg_loss_delay_samples" => "20");
46 14661668 Phil Davis
	}
47
48 3d471a14 Ermal
/*
49
 * Creates monitoring configuration file and
50 14661668 Phil Davis
 * adds appropriate static routes.
51 cdcea13f Seth Mos
 */
52
function setup_gateways_monitor() {
53 3d471a14 Ermal
	global $config, $g;
54 ffe76308 Seth Mos
55 3d471a14 Ermal
	$gateways_arr = return_gateways_array();
56
	if (!is_array($gateways_arr)) {
57
		log_error("No gateways to monitor. Apinger will not be run.");
58
		killbypid("{$g['varrun_path']}/apinger.pid");
59 3e3ff931 Ryan Dlugosz
		@unlink("{$g['varrun_path']}/apinger.status");
60 3d471a14 Ermal
		return;
61
	}
62 cdcea13f Seth Mos
63 14661668 Phil Davis
	$apinger_default = return_apinger_defaults();
64 cdcea13f Seth Mos
	$apingerconfig = <<<EOD
65
66
# pfSense apinger configuration file. Automatically Generated!
67
68
## User and group the pinger should run as
69 0534d60a Chris Buechler
user "root"
70
group "wheel"
71 cdcea13f Seth Mos
72
## Mailer to use (default: "/usr/lib/sendmail -t")
73 f040882c Renato Botelho
#mailer "/var/qmail/bin/qmail-inject"
74 cdcea13f Seth Mos
75
## Location of the pid-file (default: "/var/run/apinger.pid")
76
pid_file "{$g['varrun_path']}/apinger.pid"
77
78
## Format of timestamp (%s macro) (default: "%b %d %H:%M:%S")
79
#timestamp_format "%Y%m%d%H%M%S"
80
81
status {
82 14661668 Phil Davis
	## File where the status information should be written to
83 3e3ff931 Ryan Dlugosz
	file "{$g['varrun_path']}/apinger.status"
84 cdcea13f Seth Mos
	## Interval between file updates
85
	## when 0 or not set, file is written only when SIGUSR1 is received
86 ecb08c6a Ermal
	interval 5s
87 cdcea13f Seth Mos
}
88
89
########################################
90
# RRDTool status gathering configuration
91
# Interval between RRD updates
92
rrd interval 60s;
93
94 14661668 Phil Davis
## These parameters can be overridden in a specific alarm configuration
95 f040882c Renato Botelho
alarm default {
96 36777fe4 Ermal
	command on "/usr/local/sbin/pfSctl -c 'service reload dyndns %T' -c 'service reload ipsecdns' -c 'service reload openvpn %T' -c 'filter reload' "
97 be2a18bf Phil Davis
	command off "/usr/local/sbin/pfSctl -c 'service reload dyndns %T' -c 'service reload ipsecdns' -c 'service reload openvpn %T' -c 'filter reload' "
98 cdcea13f Seth Mos
	combine 10s
99
}
100
101 f040882c Renato Botelho
## "Down" alarm definition.
102 cdcea13f Seth Mos
## This alarm will be fired when target doesn't respond for 30 seconds.
103
alarm down "down" {
104 14661668 Phil Davis
	time {$apinger_default['down']}s
105 cdcea13f Seth Mos
}
106
107 f040882c Renato Botelho
## "Delay" alarm definition.
108 cdcea13f Seth Mos
## This alarm will be fired when responses are delayed more than 200ms
109
## it will be canceled, when the delay drops below 100ms
110
alarm delay "delay" {
111 14661668 Phil Davis
	delay_low {$apinger_default['latencylow']}ms
112
	delay_high {$apinger_default['latencyhigh']}ms
113 cdcea13f Seth Mos
}
114
115 f040882c Renato Botelho
## "Loss" alarm definition.
116 cdcea13f Seth Mos
## This alarm will be fired when packet loss goes over 20%
117
## it will be canceled, when the loss drops below 10%
118
alarm loss "loss" {
119 14661668 Phil Davis
	percent_low {$apinger_default['losslow']}
120
	percent_high {$apinger_default['losshigh']}
121 cdcea13f Seth Mos
}
122
123
target default {
124 f040882c Renato Botelho
	## How often the probe should be sent
125 14661668 Phil Davis
	interval {$apinger_default['interval']}s
126 f040882c Renato Botelho
127
	## How many replies should be used to compute average delay
128 cdcea13f Seth Mos
	## for controlling "delay" alarms
129 3c6787ed N0YB
	avg_delay_samples {$apinger_default['avg_delay_samples']}
130 f040882c Renato Botelho
131 cdcea13f Seth Mos
	## How many probes should be used to compute average loss
132 3c6787ed N0YB
	avg_loss_samples {$apinger_default['avg_loss_samples']}
133 cdcea13f Seth Mos
134
	## The delay (in samples) after which loss is computed
135
	## without this delays larger than interval would be treated as loss
136 3c6787ed N0YB
	avg_loss_delay_samples {$apinger_default['avg_loss_delay_samples']}
137 cdcea13f Seth Mos
138
	## Names of the alarms that may be generated for the target
139
	alarms "down","delay","loss"
140
141
	## Location of the RRD
142 1bce2729 Seth Mos
	#rrd file "{$g['vardb_path']}/rrd/apinger-%t.rrd"
143 cdcea13f Seth Mos
}
144
145
EOD;
146
147 74c834f1 smos
	$monitor_ips = array();
148 3d471a14 Ermal
	foreach($gateways_arr as $name => $gateway) {
149 33c06ef7 Ermal
		/* Do not monitor if such was requested */
150
		if (isset($gateway['monitor_disable']))
151
			continue;
152 3d471a14 Ermal
		if (empty($gateway['monitor']) || !is_ipaddr($gateway['monitor'])) {
153
			if (is_ipaddr($gateway['gateway']))
154
				$gateway['monitor'] = $gateway['gateway'];
155
			else /* No chance to get an ip to monitor skip target. */
156 f31ab121 Ermal
				continue;
157 3d471a14 Ermal
		}
158 f31ab121 Ermal
159 f040882c Renato Botelho
		/* if the monitor address is already used before, skip */
160 74c834f1 smos
		if(in_array($gateway['monitor'], $monitor_ips))
161
			continue;
162 f040882c Renato Botelho
163 3d471a14 Ermal
		/* Interface ip is needed since apinger will bind a socket to it. */
164 640b3a9a Seth Mos
		if (is_ipaddrv4($gateway['gateway'])) {
165
			$gwifip = find_interface_ip($gateway['interface'], true);
166 e9d156fd Ermal
			if (!is_ipaddrv4($gwifip))
167
				continue; //Skip this target
168 32a9eb18 Ermal
169
			/*
170
			 * If the gateway is the same as the monitor we do not add a
171
			 * route as this will break the routing table.
172
			 * Add static routes for each gateway with their monitor IP
173
			 * not strictly necessary but is a added level of protection.
174
			 */
175
			if (is_ipaddrv4($gateway['gateway']) && $gateway['monitor'] != $gateway['gateway']) {
176
				log_error("Removing static route for monitor {$gateway['monitor']} and adding a new route through {$gateway['gateway']}");
177
				mwexec("/sbin/route change -host " . escapeshellarg($gateway['monitor']) .
178
					" " . escapeshellarg($gateway['gateway']), true);
179
			}
180 e9d156fd Ermal
		} else if (is_ipaddrv6($gateway['gateway'])) {
181 81a3b6f5 smos
			/* link locals really need a different src ip */
182 db7a628c Renato Botelho
			if(is_linklocal($gateway['gateway'])) {
183 2c3924a1 Ermal
				$gwifip = find_interface_ipv6_ll($gateway['interface'], true);
184 81a3b6f5 smos
			} else {
185
				$gwifip = find_interface_ipv6($gateway['interface'], true);
186
			}
187 42f33846 Ermal
			if (is_linklocal($gateway['monitor']) && !strstr($gateway['monitor'], '%'))
188 17921b7e Ermal
				$gateway['monitor'] .= "%{$gateway['interface']}";
189 e9d156fd Ermal
			if (!is_ipaddrv6($gwifip))
190
				continue; //Skip this target
191 32a9eb18 Ermal
192
			/*
193
			 * If the gateway is the same as the monitor we do not add a
194
			 * route as this will break the routing table.
195
			 * Add static routes for each gateway with their monitor IP
196
			 * not strictly necessary but is a added level of protection.
197
			 */
198
			if (is_ipaddrv6($gateway['gateway']) && $gateway['monitor'] != $gateway['gateway']) {
199
				log_error("Removing static route for monitor {$gateway['monitor']} and adding a new route through {$gateway['gateway']}");
200
				mwexec("/sbin/route change -host -inet6 " . escapeshellarg($gateway['monitor']) .
201
					" " . escapeshellarg($gateway['gateway']), true);
202
			}
203 e9d156fd Ermal
		} else
204
			continue;
205 3d471a14 Ermal
206 45eb8aeb Renato Botelho
		$monitor_ips[] = $gateway['monitor'];
207 f44f8eb5 Ermal
		$apingercfg = "target \"{$gateway['monitor']}\" {\n";
208 68f291ff Ermal
		$apingercfg .= "	description \"{$name}\"\n";
209 3d471a14 Ermal
		$apingercfg .= "	srcip \"{$gwifip}\"\n";
210 3c6787ed N0YB
211
		## How often the probe should be sent
212
		if (!empty($gateway['interval']) &&  is_numeric($gateway['interval'])) {
213
			$interval = intval($gateway['interval']);	# Restrict to Integer
214
			if ($interval <  1) $interval =  1;	# Minimum
215
			if ($interval != $apinger_default['interval'])	# If not default value
216
				$apingercfg .= "	interval " . $interval . "s\n";
217
		}
218
219
		## How many replies should be used to compute average delay 
220
		## for controlling "delay" alarms
221
		if (!empty($gateway['avg_delay_samples']) && is_numeric($gateway['avg_delay_samples'])) {
222
			$avg_delay_samples = intval($gateway['avg_delay_samples']);	# Restrict to Integer
223
			if ($avg_delay_samples <  1) $avg_delay_samples =  1;	# Minimum
224
			if ($avg_delay_samples != $apinger_default['avg_delay_samples'])	# If not default value
225
				$apingercfg .= "	avg_delay_samples " . $avg_delay_samples . "\n";
226
		}
227
228
		## How many probes should be used to compute average loss
229
		if (!empty($gateway['avg_loss_samples']) && is_numeric($gateway['avg_loss_samples'])) {
230
			$avg_loss_samples = intval($gateway['avg_loss_samples']);	# Restrict to Integer
231
			if ($avg_loss_samples < 1) $avg_loss_samples = 1;	# Minimum
232
			if ($avg_loss_samples != $apinger_default['avg_loss_samples'])	# If not default value
233
				$apingercfg .= "	avg_loss_samples " . $avg_loss_samples . "\n";
234
		}
235
236
		## The delay (in samples) after which loss is computed
237
		## without this delays larger than interval would be treated as loss
238
		if (!empty($gateway['avg_loss_delay_samples']) && is_numeric($gateway['avg_loss_delay_samples'])) {
239
			$avg_loss_delay_samples = intval($gateway['avg_loss_delay_samples']);	# Restrict to Integer
240
			if ($avg_loss_delay_samples < 1) $avg_loss_delay_samples = 1;	# Minimum
241
			if ($avg_loss_delay_samples != $apinger_default['avg_loss_delay_samples'])	# If not default value
242
				$apingercfg .= "	avg_loss_delay_samples " . $avg_loss_delay_samples . "\n";
243
		}
244
245 3d471a14 Ermal
		$alarms = "";
246 f44f8eb5 Ermal
		$alarmscfg = "";
247 3d471a14 Ermal
		$override = false;
248 02a8dab0 ccesario
		if (!empty($gateway['losslow'])) {
249 68f291ff Ermal
			$alarmscfg .= "alarm loss \"{$name}loss\" {\n";
250 3d471a14 Ermal
			$alarmscfg .= "\tpercent_low {$gateway['losslow']}\n";
251 f040882c Renato Botelho
			$alarmscfg .= "\tpercent_high {$gateway['losshigh']}\n";
252 3d471a14 Ermal
			$alarmscfg .= "}\n";
253 68f291ff Ermal
			$alarms .= "\"{$name}loss\"";
254 3d471a14 Ermal
			$override = true;
255
		} else {
256 023920e7 Ermal
			if ($override == true)
257 3d471a14 Ermal
				$alarms .= ",";
258
			$alarms .= "\"loss\"";
259
			$override = true;
260
		}
261
		if (!empty($gateway['latencylow'])) {
262 68f291ff Ermal
			$alarmscfg .= "alarm delay \"{$name}delay\" {\n";
263 3d471a14 Ermal
			$alarmscfg .= "\tdelay_low {$gateway['latencylow']}ms\n";
264
			$alarmscfg .= "\tdelay_high {$gateway['latencyhigh']}ms\n";
265
			$alarmscfg .= "}\n";
266
			if ($override == true)
267
				$alarms .= ",";
268 68f291ff Ermal
			$alarms .= "\"{$name}delay\"";
269 3d471a14 Ermal
			$override = true;
270
		} else {
271
			if ($override == true)
272
				$alarms .= ",";
273
			$alarms .= "\"delay\"";
274
			$override = true;
275
		}
276
		if (!empty($gateway['down'])) {
277 68f291ff Ermal
			$alarmscfg .= "alarm down \"{$name}down\" {\n";
278 3d471a14 Ermal
			$alarmscfg .= "\ttime {$gateway['down']}s\n";
279
			$alarmscfg .= "}\n";
280
			if ($override == true)
281
				$alarms .= ",";
282 68f291ff Ermal
			$alarms .= "\"{$name}down\"";
283 3d471a14 Ermal
			$override = true;
284
		} else {
285
			if ($override == true)
286
				$alarms .= ",";
287
			$alarms .= "\"down\"";
288
			$override = true;
289 cdcea13f Seth Mos
		}
290 3d471a14 Ermal
		if ($override == true)
291
			$apingercfg .= "\talarms override {$alarms};\n";
292
293 81f19476 Renato Botelho
		if (isset($gateway['force_down']))
294
			$apingercfg .= "\tforce_down on\n";
295
296 3d471a14 Ermal
		$apingercfg .= "	rrd file \"{$g['vardb_path']}/rrd/{$gateway['name']}-quality.rrd\"\n";
297
		$apingercfg .= "}\n";
298
		$apingercfg .= "\n";
299
300 023920e7 Ermal
		$apingerconfig .= $alarmscfg;
301
		$apingerconfig .= $apingercfg;
302 cdcea13f Seth Mos
	}
303 de82ec90 Ermal
	@file_put_contents("{$g['varetc_path']}/apinger.conf", $apingerconfig);
304 292da16b Ermal
	unset($apingerconfig);
305 cdcea13f Seth Mos
306 20f26a50 Ermal
	if (is_dir("{$g['tmp_path']}"))
307
		chmod("{$g['tmp_path']}", 01777);
308 17649c87 Ermal
	if (!is_dir("{$g['vardb_path']}/rrd"))
309 21934843 jim-p
		mkdir("{$g['vardb_path']}/rrd", 0775);
310 17649c87 Ermal
311
	@chown("{$g['vardb_path']}/rrd", "nobody");
312
313 746f0afb Ermal
	if (isvalidpid("{$g['varrun_path']}/apinger.pid"))
314
		sigkillbypid("{$g['varrun_path']}/apinger.pid", "HUP");
315
	else {
316
		/* start a new apinger process */
317
		@unlink("{$g['varrun_path']}/apinger.status");
318
		sleep(1);
319
		mwexec_bg("/usr/local/sbin/apinger -c {$g['varetc_path']}/apinger.conf");
320
		sleep(1);
321
		sigkillbypid("{$g['varrun_path']}/apinger.pid", "USR1");
322
	}
323 4f060616 Ermal
324 cdcea13f Seth Mos
	return 0;
325
}
326
327
/* return the status of the apinger targets as a array */
328 3d471a14 Ermal
function return_gateways_status($byname = false) {
329 ae9618af Ermal
	global $config, $g;
330 cdcea13f Seth Mos
331
	$apingerstatus = array();
332 2db93ddb Ermal
	/* Always get the latest status from apinger */
333
	if (file_exists("{$g['varrun_path']}/apinger.pid"))
334
                sigkillbypid("{$g['varrun_path']}/apinger.pid", "USR1");
335 3e3ff931 Ryan Dlugosz
	if (file_exists("{$g['varrun_path']}/apinger.status")) {
336
		$apingerstatus = file("{$g['varrun_path']}/apinger.status");
337 2db93ddb Ermal
	} else
338
		$apingerstatus = array();
339 cdcea13f Seth Mos
340 67ee1ec5 Ermal Luçi
	$status = array();
341 cdcea13f Seth Mos
	foreach($apingerstatus as $line) {
342 75466131 Ermal
		$info = explode("|", $line);
343 3d471a14 Ermal
		if ($byname == false)
344
			$target = $info[0];
345
		else
346
			$target = $info[2];
347 47c48e28 smos
348 dea0921d Ermal
		$status[$target] = array();
349 3d471a14 Ermal
		$status[$target]['monitorip'] = $info[0];
350 79b7f498 Ermal
		$status[$target]['srcip'] = $info[1];
351
		$status[$target]['name'] = $info[2];
352
		$status[$target]['lastcheck'] = $info[5] ? date('r', $info[5]) : date('r');
353 603f19f0 smos
		$status[$target]['delay'] = empty($info[6]) ? "0ms" : round($info[6], 1) ."ms" ;
354
		$status[$target]['loss'] = empty($info[7]) ? "0.0%" : round($info[7], 1) . "%";
355 79b7f498 Ermal
		$status[$target]['status'] = trim($info[8]);
356 cdcea13f Seth Mos
	}
357 68f291ff Ermal
358 47c48e28 smos
	/* tack on any gateways that have monitoring disabled
359
	 * or are down, which could cause gateway groups to fail */
360 16106d2e smos
	$gateways_arr = return_gateways_array();
361
	foreach($gateways_arr as $gwitem) {
362 2ba95a31 Ermal
		if(!isset($gwitem['monitor_disable']))
363 fd34d6a9 Ermal
			continue;
364
		if(!is_ipaddr($gwitem['monitorip'])) {
365
			$realif = $gwitem['interface'];
366
			$tgtip = get_interface_gateway($realif);
367
			if (!is_ipaddr($tgtip))
368
				$tgtip = "none";
369
			$srcip = find_interface_ip($realif);
370
		} else {
371
			$tgtip = $gwitem['monitorip'];
372
			$srcip = find_interface_ip($realif);
373
		}
374
		if($byname == true)
375
			$target = $gwitem['name'];
376
		else
377
			$target = $tgtip;
378
379
		/* failsafe for down interfaces */
380
		if($target == "none") {
381
			$target = $gwitem['name'];
382
			$status[$target]['name'] = $gwitem['name'];
383
			$status[$target]['lastcheck'] = date('r');
384
			$status[$target]['delay'] = "0.0ms";
385
			$status[$target]['loss'] = "100.0%";
386
			$status[$target]['status'] = "down";
387
		} else {
388
			$status[$target]['monitorip'] = $tgtip;
389
			$status[$target]['srcip'] = $srcip;
390
			$status[$target]['name'] = $gwitem['name'];
391
			$status[$target]['lastcheck'] = date('r');
392
			$status[$target]['delay'] = "0.0ms";
393
			$status[$target]['loss'] = "0.0%";
394
			$status[$target]['status'] = "none";
395 16106d2e smos
		}
396
	}
397 cdcea13f Seth Mos
	return($status);
398 17623ab5 Bill Marquette
}
399
400 2328dcc5 Seth Mos
/* Return all configured gateways on the system */
401 06b8d43c Renato Botelho
function return_gateways_array($disabled = false, $localhost = false, $inactive = false) {
402 8d3556c2 gnhb
	global $config, $g;
403 7901dff5 Ermal Luçi
404 c66b4242 Seth Mos
	$gateways_arr = array();
405
406 74c834f1 smos
	$found_defaultv4 = 0;
407
	$found_defaultv6 = 0;
408
409 33e71f10 jim-p
	// Ensure the interface cache is up to date first
410
	$interfaces = get_interface_arr(true);
411 3930a9c0 smos
	$interfaces_v4 = array();
412
	$interfaces_v6 = array();
413
414 23d9f686 Renato Botelho
	$i = -1;
415 3d471a14 Ermal
	/* Process/add all the configured gateways. */
416 ef05ae5f Ermal
	if (is_array($config['gateways']['gateway_item'])) {
417 1500614c Ermal
		foreach ($config['gateways']['gateway_item'] as $gateway) {
418 23d9f686 Renato Botelho
			/* Increment it here to do not skip items */
419
			$i++;
420
421 06b8d43c Renato Botelho
			if (empty($config['interfaces'][$gateway['interface']])) {
422
				if ($inactive === false)
423
					continue;
424
				else
425
					$gateway['inactive'] = true;
426
			}
427 3930a9c0 smos
			$wancfg = $config['interfaces'][$gateway['interface']];
428 1500614c Ermal
429
			/* skip disabled interfaces */
430 ee574a9e Renato Botelho
			if ($disabled === false && (!isset($wancfg['enable']) || isset($gateway['disabled'])))
431 1500614c Ermal
				continue;
432 c1d36d26 smos
433 3930a9c0 smos
			/* if the gateway is dynamic and we can find the IPv4, Great! */
434 26190b11 Renato Botelho
			if (empty($gateway['gateway']) || $gateway['gateway'] == "dynamic" || $gateway['gateway'] == "dynamic6") {
435 1500614c Ermal
				if ($gateway['ipprotocol'] == "inet") {
436
					/* we know which interfaces is dynamic, this should be made a function */
437 65cfd0ca Renato Botelho
					$gateway['gateway'] = get_interface_gateway($gateway['interface']);
438
					/* no IP address found, set to dynamic */
439
					if (!is_ipaddrv4($gateway['gateway']))
440
						$gateway['gateway'] = "dynamic";
441
					$gateway['dynamic'] = true;
442 74c834f1 smos
				}
443 c1d36d26 smos
444 1500614c Ermal
				/* if the gateway is dynamic6 and we can find the IPv6, Great! */
445 8e78c82c Renato Botelho
				else if ($gateway['ipprotocol'] == "inet6") {
446 1500614c Ermal
					/* we know which interfaces is dynamic, this should be made a function, and for v6 too */
447 65cfd0ca Renato Botelho
					$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
448
					/* no IPv6 address found, set to dynamic6 */
449
					if (!is_ipaddrv6($gateway['gateway']))
450
						$gateway['gateway'] = "dynamic6";
451
					$gateway['dynamic'] = true;
452 7671c940 Seth Mos
				}
453 1500614c Ermal
			} else {
454
				/* getting this detection right is hard at this point because we still don't
455
				 * store the address family in the gateway item */
456
				if (is_ipaddrv4($gateway['gateway']))
457
					$gateway['ipprotocol'] = "inet";
458
				else if(is_ipaddrv6($gateway['gateway']))
459
					$gateway['ipprotocol'] = "inet6";
460 2328dcc5 Seth Mos
			}
461 c1d36d26 smos
462 33c06ef7 Ermal
			if (isset($gateway['monitor_disable']))
463
				$gateway['monitor_disable'] = true;
464
			else if (empty($gateway['monitor']))
465 2328dcc5 Seth Mos
				$gateway['monitor'] = $gateway['gateway'];
466 3d471a14 Ermal
467 883c53c9 Ermal Lu?i
			$gateway['friendlyiface'] = $gateway['interface'];
468 c1d36d26 smos
469
			/* special treatment for tunnel interfaces */
470 1500614c Ermal
			if ($gateway['ipprotocol'] == "inet6") {
471 33e71f10 jim-p
				$gateway['interface'] = get_real_interface($gateway['interface'], "inet6", false, false);
472 1500614c Ermal
				$interfaces_v6[$gateway['friendlyiface']] = $gateway['friendlyiface'];
473
			} else {
474 33e71f10 jim-p
				$gateway['interface'] = get_real_interface($gateway['interface'], "all", false, false);
475 1500614c Ermal
				$interfaces_v4[$gateway['friendlyiface']] = $gateway['friendlyiface'];
476
			}
477 74c834f1 smos
478
			/* entry has a default flag, use it */
479
			if (isset($gateway['defaultgw'])) {
480 1500614c Ermal
				if ($gateway['ipprotocol'] == "inet") {
481 74c834f1 smos
					$gateway['defaultgw'] = true;
482
					$found_defaultv4 = 1;
483 1500614c Ermal
				} else if ($gateway['ipprotocol'] == "inet6") {
484 74c834f1 smos
					$gateway['defaultgw'] = true;
485
					$found_defaultv6 = 1;
486
				}
487
			}
488 3d471a14 Ermal
			/* include the gateway index as the attribute */
489
			$gateway['attribute'] = $i;
490 2328dcc5 Seth Mos
491
			$gateways_arr[$gateway['name']] = $gateway;
492
		}
493 c1d36d26 smos
	}
494 1500614c Ermal
	unset($gateway);
495 883c53c9 Ermal Lu?i
496 ef05ae5f Ermal
	/* Loop through all interfaces with a gateway and add it to a array */
497
	if ($disabled == false)
498
		$iflist = get_configured_interface_with_descr();
499
	else
500
		$iflist = get_configured_interface_with_descr(false, true);
501
502 c3a0d2a5 Seth Mos
	/* Process/add dynamic v4 gateways. */
503 883c53c9 Ermal Lu?i
	foreach($iflist as $ifname => $friendly ) {
504 3d471a14 Ermal
		if(! interface_has_gateway($ifname))
505 883c53c9 Ermal Lu?i
			continue;
506 3d471a14 Ermal
507 86df2846 jim-p
		if (empty($config['interfaces'][$ifname]))
508
			continue;
509
510
		$ifcfg = &$config['interfaces'][$ifname];
511 1500614c Ermal
		if(!isset($ifcfg['enable']))
512 e62fe748 Ermal
			continue;
513
514 1500614c Ermal
		if(!empty($ifcfg['ipaddr']) && is_ipaddrv4($ifcfg['ipaddr']))
515 74c834f1 smos
			continue;
516 3930a9c0 smos
517 1500614c Ermal
		if (isset($interfaces_v4[$ifname]))
518 3930a9c0 smos
			continue;
519 f040882c Renato Botelho
520 74c834f1 smos
		$ctype = "";
521
		switch($ifcfg['ipaddr']) {
522
			case "dhcp":
523
			case "pppoe":
524
			case "pptp":
525 b2ff5d17 smos
			case "ppp":
526 74c834f1 smos
				$ctype = strtoupper($ifcfg['ipaddr']);
527
				break;
528 daac437f jim-p
			default:
529 c822154c jim-p
				if (substr($ifcfg['if'], 0, 4) ==  "ovpn")
530 daac437f jim-p
					$ctype = "VPNv4";
531
				break;
532 74c834f1 smos
		}
533
		$ctype = "_". strtoupper($ctype);
534
535 883c53c9 Ermal Lu?i
		$gateway = array();
536
		$gateway['dynamic'] = false;
537 c3a0d2a5 Seth Mos
		$gateway['ipprotocol'] = "inet";
538 883c53c9 Ermal Lu?i
		$gateway['gateway'] = get_interface_gateway($ifname, $gateway['dynamic']);
539
		$gateway['interface'] = get_real_interface($ifname);
540
		$gateway['friendlyiface'] = $ifname;
541 74c834f1 smos
		$gateway['name'] = "{$friendly}{$ctype}";
542 883c53c9 Ermal Lu?i
		$gateway['attribute'] = "system";
543 f040882c Renato Botelho
544 74c834f1 smos
		if (($gateway['dynamic'] === "default") && ($found_defaultv4 == 0)) {
545 999111cb Ermal
			$gateway['defaultgw'] = true;
546
			$gateway['dynamic'] = true;
547 74c834f1 smos
			$found_defaultv4 = 1;
548 999111cb Ermal
		}
549 883c53c9 Ermal Lu?i
		/* Loopback dummy for dynamic interfaces without a IP */
550 c3a0d2a5 Seth Mos
		if (!is_ipaddrv4($gateway['gateway']) && $gateway['dynamic'] == true)
551 999111cb Ermal
			$gateway['gateway'] = "dynamic";
552 3439b033 Seth Mos
553 883c53c9 Ermal Lu?i
		/* automatically skip known static and dynamic gateways we have a array entry for */
554
		foreach($gateways_arr as $gateway_item) {
555 c3a0d2a5 Seth Mos
			if ((($ifname == $gateway_item['friendlyiface'] && $friendly == $gateway_item['name'])&& ($gateway['ipprotocol'] == $gateway_item['ipprotocol'])) ||
556
				($ifname == $gateway_item['friendlyiface'] && $gateway_item['dynamic'] == true) && ($gateway['ipprotocol'] == $gateway_item['ipprotocol']))
557 7bed8222 Ermal
					continue 2;
558 883c53c9 Ermal Lu?i
		}
559 c66b4242 Seth Mos
560 c3a0d2a5 Seth Mos
		if (is_ipaddrv4($gateway['gateway']))
561 883c53c9 Ermal Lu?i
			$gateway['monitor'] = $gateway['gateway'];
562 c65e1e0d Ermal
563 74c834f1 smos
		$gateway['descr'] = "Interface {$friendly}{$ctype} Gateway";
564 c3a0d2a5 Seth Mos
		$gateways_arr[$gateway['name']] = $gateway;
565
	}
566 1500614c Ermal
	unset($gateway);
567 c3a0d2a5 Seth Mos
568
	/* Process/add dynamic v6 gateways. */
569
	foreach($iflist as $ifname => $friendly ) {
570 0715ad50 jim-p
		/* If the user has disabled IPv6, they probably don't want any IPv6 gateways. */
571
		if (!isset($config['system']['ipv6allow']))
572
			break;
573
574 67102344 smos
		if(! interface_has_gatewayv6($ifname))
575 c3a0d2a5 Seth Mos
			continue;
576
577
		if (empty($config['interfaces'][$ifname]))
578
			continue;
579
580
		$ifcfg = &$config['interfaces'][$ifname];
581 74c834f1 smos
		if(!isset($ifcfg['enable']))
582
			continue;
583
584 1500614c Ermal
		if(!empty($ifcfg['ipaddrv6']) && is_ipaddrv6($ifcfg['ipaddrv6']))
585
			continue;
586 f040882c Renato Botelho
587 1500614c Ermal
		if(isset($interfaces_v6[$ifname]))
588 3930a9c0 smos
			continue;
589
590 74c834f1 smos
		$ctype = "";
591
		switch($ifcfg['ipaddrv6']) {
592 c0b1bc81 smos
			case "slaac":
593 74c834f1 smos
			case "dhcp6":
594
			case "6to4":
595
			case "6rd":
596
				$ctype = strtoupper($ifcfg['ipaddrv6']);
597
				break;
598 daac437f jim-p
			default:
599 b31247af Ermal
				$tunnelif = substr($ifname['if'], 0, 3);
600 c822154c jim-p
				if (substr($ifcfg['if'], 0, 4) ==  "ovpn")
601 daac437f jim-p
					$ctype = "VPNv6";
602 b31247af Ermal
				else if ($tunnelif == "gif" || $tunnelif == "gre")
603 c32a6b82 Ermal
					$ctype = "TUNNELv6";
604 daac437f jim-p
				break;
605 74c834f1 smos
		}
606
		$ctype = "_". strtoupper($ctype);
607 c3a0d2a5 Seth Mos
608
		$gateway = array();
609
		$gateway['dynamic'] = false;
610
		$gateway['ipprotocol'] = "inet6";
611
		$gateway['gateway'] = get_interface_gateway_v6($ifname, $gateway['dynamic']);
612 909de400 Ermal
		$gateway['interface'] = get_real_interface($ifname, "inet6");
613 d500e296 smos
		switch($ifcfg['ipaddrv6']) {
614
			case "6rd":
615 909de400 Ermal
			case "6to4":
616 d500e296 smos
				$gateway['dynamic'] = "default";
617
				break;
618
		}
619 c3a0d2a5 Seth Mos
		$gateway['friendlyiface'] = $ifname;
620 74c834f1 smos
		$gateway['name'] = "{$friendly}{$ctype}";
621 c3a0d2a5 Seth Mos
		$gateway['attribute'] = "system";
622 f040882c Renato Botelho
623 74c834f1 smos
		if (($gateway['dynamic'] === "default")  && ($found_defaultv6 == 0)) {
624 c3a0d2a5 Seth Mos
			$gateway['defaultgw'] = true;
625
			$gateway['dynamic'] = true;
626 74c834f1 smos
			$found_defaultv6 = 1;
627 c3a0d2a5 Seth Mos
		}
628
629
		/* Loopback dummy for dynamic interfaces without a IP */
630
		if (!is_ipaddrv6($gateway['gateway']) && $gateway['dynamic'] == true)
631 791d3ac9 Seth Mos
			$gateway['gateway'] = "dynamic6";
632 c3a0d2a5 Seth Mos
633
		/* automatically skip known static and dynamic gateways we have a array entry for */
634
		foreach($gateways_arr as $gateway_item) {
635
			if ((($ifname == $gateway_item['friendlyiface'] && $friendly == $gateway_item['name']) && ($gateway['ipprotocol'] == $gateway_item['ipprotocol'])) ||
636
				($ifname == $gateway_item['friendlyiface'] && $gateway_item['dynamic'] == true) && ($gateway['ipprotocol'] == $gateway_item['ipprotocol']))
637
					continue 2;
638
		}
639
640
		if (is_ipaddrv6($gateway['gateway']))
641
			$gateway['monitor'] = $gateway['gateway'];
642
643 74c834f1 smos
		$gateway['descr'] = "Interface {$friendly}{$ctype} Gateway";
644 c3a0d2a5 Seth Mos
		$gateways_arr[$gateway['name']] = $gateway;
645 c66b4242 Seth Mos
	}
646 1500614c Ermal
	unset($gateway);
647 6fdea6a2 smos
648 08c3810c Renato Botelho
	/* FIXME: Should this be enabled.
649
	 * Some interface like wan might be default but have no info recorded
650
	 * the config. */
651
	/* this is a fallback if all else fails and we want to get packets out @smos */
652
	if ($found_defaultv4 == 0 || $found_defaultv6 == 0) {
653
		foreach ($gateways_arr as &$gateway) {
654
			if (($gateway['friendlyiface'] == "wan") && ($found_defaultv4 == 0) && (!isset($gateway['ipprotocol']) || ($gateway['ipprotocol'] == "inet"))) {
655
				if (file_exists("{$g['tmp_path']}/{$gateway['interface']}_defaultgw")) {
656
					$gateway['defaultgw'] = true;
657
					$found_defaultv4 = 1;
658
				}
659
			}
660
			if (($gateway['friendlyiface'] == "wan") && ($found_defaultv6 == 0) && ($gateway['ipprotocol'] == "inet6")) {
661
				if (file_exists("{$g['tmp_path']}/{$gateway['interface']}_defaultgwv6")) {
662
					$gateway['defaultgw'] = true;
663
					$found_defaultv6 = 1;
664
				}
665
			}
666
		}
667
	}
668
669 6fdea6a2 smos
	if($localhost === true) {
670
		/* attach localhost for Null routes */
671
		$gwlo4 = array();
672
		$gwlo4['name'] = "Null4";
673
		$gwlo4['interface'] = "lo0";
674
		$gwlo4['ipprotocol'] = "inet";
675
		$gwlo4['gateway'] = "127.0.0.1";
676
		$gwlo6 = array();
677
		$gwlo6['name'] = "Null6";
678
		$gwlo6['interface'] = "lo0";
679
		$gwlo6['ipprotocol'] = "inet6";
680
		$gwlo6['gateway'] = "::1";
681
		$gateways_arr['Null4'] = $gwlo4;
682
		$gateways_arr['Null6'] = $gwlo6;
683
	}
684 c66b4242 Seth Mos
	return($gateways_arr);
685
}
686
687 fd3515f2 jim-p
function fixup_default_gateway($ipprotocol, $gateways_status, $gateways_arr) {
688
	global $config, $g;
689
	/*
690
	 * NOTE: The code below is meant to replace the default gateway when it goes down.
691
	 *	This facilitates services running on pfSense itself and are not handled by a PBR to continue working.
692
	 */
693
	$upgw = "";
694
	$dfltgwdown = false;
695
	$dfltgwfound = false;
696
	foreach ($gateways_arr as $gwname => $gwsttng) {
697
		if (($gwsttng['ipprotocol'] == $ipprotocol) && isset($gwsttng['defaultgw'])) {
698
			$dfltgwfound = true;
699
			$dfltgwname = $gwname;
700
			if (!isset($gwsttng['monitor_disable']) && stristr($gateways_status[$gwname]['status'], "down"))
701
				$dfltgwdown = true;
702
		}
703
		/* Keep a record of the last up gateway */
704
		/* XXX: Blacklist lan for now since it might cause issues to those who have a gateway set for it */
705
		if (empty($upgw) && ($gwsttng['ipprotocol'] == $ipprotocol) && (isset($gwsttng['monitor_disable']) || !stristr($gateways_status[$gwname]['status'], "down")) && $gwsttng[$gwname]['friendlyiface'] != "lan")
706
			$upgw = $gwname;
707
		if ($dfltgwdown == true && !empty($upgw))
708
			break;
709
	}
710
	if ($dfltgwfound == false) {
711
		$gwname = convert_friendly_interface_to_friendly_descr("wan");
712
		if (!empty($gateways_status[$gwname]) && stristr($gateways_status[$gwname]['status'], "down"))
713
			$dfltgwdown = true;
714
	}
715
	if ($dfltgwdown == true && !empty($upgw)) {
716
		if (preg_match("/dynamic/i", $gateways_arr[$upgw]['gateway']))
717
			$gateways_arr[$upgw]['gateway'] = get_interface_gateway($gateways_arr[$upgw]['friendlyiface']);
718
		if (is_ipaddr($gateways_arr[$upgw]['gateway'])) {
719
			log_error("Default gateway down setting {$upgw} as default!");
720
			if(is_ipaddrv6($gateways_arr[$upgw]['gateway'])) {
721
				$inetfamily = "-inet6";
722
			} else {
723
				$inetfamily = "-inet";
724
			}
725
			mwexec("/sbin/route change {$inetfamily} default {$gateways_arr[$upgw]['gateway']}");
726
		}
727
	} else {
728
		$defaultgw = trim(`/sbin/route -n get -{$ipprotocol} default | /usr/bin/grep gateway | /usr/bin/sed 's/gateway://g'`, " \n");
729
		if(is_ipaddrv6($gateways_arr[$dfltgwname]['gateway'])) {
730
			$inetfamily = "-inet6";
731
		} else {
732
			$inetfamily = "-inet";
733
		}
734
		if ($defaultgw != $gateways_arr[$dfltgwname]['gateway'])
735
			mwexec("/sbin/route change {$inetfamily} default {$gateways_arr[$dfltgwname]['gateway']}");
736
	}
737
}
738
739 3d471a14 Ermal
/*
740
 * Return an array with all gateway groups with name as key
741 fd8eeda5 Seth Mos
 * All gateway groups will be processed before returning the array.
742 3d471a14 Ermal
 */
743 fd8eeda5 Seth Mos
function return_gateway_groups_array() {
744 962625aa Ermal
	global $config, $g;
745 fd8eeda5 Seth Mos
746
	/* fetch the current gateways status */
747 3d471a14 Ermal
	$gateways_status = return_gateways_status(true);
748 fd8eeda5 Seth Mos
	$gateways_arr = return_gateways_array();
749
	$gateway_groups_array = array();
750
751 7af360ce Ermal
	if (isset($config['system']['gw_switch_default'])) {
752 fd3515f2 jim-p
		fixup_default_gateway("inet", $gateways_status, $gateways_arr);
753
		fixup_default_gateway("inet6", $gateways_status, $gateways_arr);
754 ee7f1647 Ermal
	}
755 fd8eeda5 Seth Mos
	if (is_array($config['gateways']['gateway_group'])) {
756 1500614c Ermal
		$carplist = get_configured_carp_interface_list();
757
		foreach ($config['gateways']['gateway_group'] as $group) {
758 5aa68a55 Renato Botelho
			/* create array with group gateways members separated by tier */
759 fd8eeda5 Seth Mos
			$tiers = array();
760 3d471a14 Ermal
			$backupplan = array();
761 1500614c Ermal
			$gwvip_arr = array();
762
			foreach ($group['item'] as $item) {
763 dea0921d Ermal
				list($gwname, $tier, $vipname) = explode("|", $item);
764 1500614c Ermal
765
				if (is_ipaddr($carplist[$vipname])) {
766 22234bbb Renato Botelho
					if (!is_array($gwvip_arr[$group['name']]))
767 1500614c Ermal
						$gwvip_arr[$group['name']] = array();
768 ab1112da smos
					$gwvip_arr[$group['name']][$gwname] = $vipname;
769 1500614c Ermal
				}
770 3d471a14 Ermal
771
				/* Do it here rather than reiterating again the group in case no member is up. */
772 dea0921d Ermal
				if (!is_array($backupplan[$tier]))
773
					$backupplan[$tier] = array();
774 d8bf779b Ermal
				$backupplan[$tier][] = $gwname;
775 3d471a14 Ermal
776 fd8eeda5 Seth Mos
				/* check if the gateway is available before adding it to the array */
777 e0ba24f7 smos
				if (is_array($gateways_status[$gwname])) {
778 54b78cc1 Ermal
					$status = $gateways_status[$gwname];
779 3d471a14 Ermal
					$gwdown = false;
780 9af4b31b Ermal
					if (stristr($status['status'], "down")) {
781 50006cca PiBa-NL
						$msg = sprintf(gettext("MONITOR: %s is down, removing from routing group {$group['name']}"), $gwname);
782 3d471a14 Ermal
						$gwdown = true;
783
					} else if (stristr($status['status'], "loss") && strstr($group['trigger'], "loss")) {
784
						/* packet loss */
785 50006cca PiBa-NL
						$msg = sprintf(gettext("MONITOR: %s has packet loss, removing from routing group {$group['name']}"), $gwname);
786 3d471a14 Ermal
						$gwdown = true;
787
					} else if (stristr($status['status'], "delay") && strstr($group['trigger'] , "latency")) {
788
						/* high latency */
789 50006cca PiBa-NL
						$msg = sprintf(gettext("MONITOR: %s has high latency, removing from routing group {$group['name']}"), $gwname);
790 3d471a14 Ermal
						$gwdown = true;
791
					}
792
					if ($gwdown == true) {
793 9f1d61d3 Scott Ullrich
						log_error($msg);
794
						notify_via_growl($msg);
795 10c3d4c0 Scott Ullrich
						notify_via_smtp($msg);
796 e0ba24f7 smos
					} else {
797 857ce5f3 Seth Mos
						/* Online add member */
798 dea0921d Ermal
						if (!is_array($tiers[$tier]))
799
							$tiers[$tier] = array();
800 857ce5f3 Seth Mos
						$tiers[$tier][] = $gwname;
801 e0ba24f7 smos
					}
802 33c06ef7 Ermal
				} else if (isset($gateways_arr[$gwname]['monitor_disable']))
803
					$tiers[$tier][] = $gwname;
804 fd8eeda5 Seth Mos
			}
805
			$tiers_count = count($tiers);
806 1500614c Ermal
			if ($tiers_count == 0) {
807 fd8eeda5 Seth Mos
				/* Oh dear, we have no members! Engage Plan B */
808 9132ae35 Ermal
				if (!$g['booting']) {
809 50006cca PiBa-NL
					$msg = gettext("Gateways status could not be determined, considering all as up/active. (Group: {$group['name']})");
810 9132ae35 Ermal
					log_error($msg);
811
					notify_via_growl($msg);
812 72b4a1e8 jim-p
					//notify_via_smtp($msg);
813 9132ae35 Ermal
				}
814 3d471a14 Ermal
				$tiers = $backupplan;
815 fd8eeda5 Seth Mos
			}
816 09ae0c17 Seth Mos
			/* sort the tiers array by the tier key */
817
			ksort($tiers);
818 3d471a14 Ermal
819 fd8eeda5 Seth Mos
			/* we do not really foreach the tiers as we stop after the first tier */
820 1500614c Ermal
			foreach ($tiers as $tieridx => $tier) {
821 fd8eeda5 Seth Mos
				/* process all gateways in this tier */
822 1500614c Ermal
				foreach ($tier as $member) {
823 fd8eeda5 Seth Mos
					/* determine interface gateway */
824 5f53260a Ermal
					if (isset($gateways_arr[$member])) {
825
						$gateway = $gateways_arr[$member];
826
						$int = $gateway['interface'];
827
						$gatewayip = "";
828 f040882c Renato Botelho
						if(is_ipaddr($gateway['gateway']))
829 5f53260a Ermal
							$gatewayip = $gateway['gateway'];
830 1500614c Ermal
						else if (!empty($int))
831 5f53260a Ermal
							$gatewayip = get_interface_gateway($gateway['friendlyiface']);
832 f040882c Renato Botelho
833 1500614c Ermal
						if (!empty($int) && is_ipaddr($gatewayip)) {
834 3d471a14 Ermal
							$groupmember = array();
835
							$groupmember['int']  = $int;
836
							$groupmember['gwip']  = $gatewayip;
837
							$groupmember['weight']  = isset($gateway['weight']) ? $gateway['weight'] : 1;
838 22234bbb Renato Botelho
							if (is_array($gwvip_arr[$group['name']])&& !empty($gwvip_arr[$group['name']][$member]))
839
								$groupmember['vip'] = $gwvip_arr[$group['name']][$member];
840 44b054ce smos
							$gateway_groups_array[$group['name']]['ipprotocol'] = $gateway['ipprotocol'];
841 3d471a14 Ermal
							$gateway_groups_array[$group['name']][] = $groupmember;
842
						}
843 fd8eeda5 Seth Mos
					}
844
				}
845
				/* we should have the 1st available tier now, exit stage left */
846 1500614c Ermal
				if (count($gateway_groups_array[$group['name']]) > 0)
847 47c48e28 smos
					break;
848
				else
849 1500614c Ermal
					log_error("GATEWAYS: Group {$group['name']} did not have any gateways up on tier {$tieridx}!");
850 fd8eeda5 Seth Mos
			}
851
		}
852
	}
853 1500614c Ermal
854 fe22a89b Ermal
	return ($gateway_groups_array);
855 fd8eeda5 Seth Mos
}
856
857 2468ae76 Scott Ullrich
/* Update DHCP WAN Interface ip address in gateway group item */
858
function dhclient_update_gateway_groups_defaultroute($interface = "wan") {
859
	global $config, $g;
860 f040882c Renato Botelho
	foreach($config['gateways']['gateway_item'] as & $gw) {
861 2468ae76 Scott Ullrich
		if($gw['interface'] == $interface) {
862
			$current_gw = get_interface_gateway($interface);
863
			if($gw['gateway'] <> $current_gw) {
864
				$gw['gateway'] = $current_gw;
865
				$changed = true;
866
			}
867
		}
868
	}
869
	if($changed && $current_gw)
870 addc0439 Renato Botelho
		write_config(sprintf(gettext('Updating gateway group gateway for %1$s - new gateway is %2$s'), $interfac, $current_gw));
871 2468ae76 Scott Ullrich
}
872 fd8eeda5 Seth Mos
873 6dc3a5c2 Ermal Lu?i
function lookup_gateway_ip_by_name($name) {
874 fe22a89b Ermal
875 fbf0d4d3 smos
	$gateways_arr = return_gateways_array(false, true);
876 f040882c Renato Botelho
	foreach ($gateways_arr as $gname => $gw) {
877 d97eccf9 Renato Botelho
		if ($gw['name'] === $name || $gname === $name)
878 f040882c Renato Botelho
			return $gw['gateway'];
879
	}
880 66a96e72 Ermal
881
	return false;
882 6dc3a5c2 Ermal Lu?i
}
883
884
function lookup_gateway_monitor_ip_by_name($name) {
885 fe22a89b Ermal
886 f040882c Renato Botelho
	$gateways_arr = return_gateways_array(false, true);
887 fe22a89b Ermal
	if (!empty($gateways_arr[$name])) {
888
		$gateway = $gateways_arr[$name];
889 68f291ff Ermal
		if(!is_ipaddr($gateway['monitor']))
890
			return $gateway['gateway'];
891 6dc3a5c2 Ermal Lu?i
892 9fd19334 gnhb
		return $gateway['monitor'];
893 f040882c Renato Botelho
	}
894 fe22a89b Ermal
895 f040882c Renato Botelho
	return (false);
896 6dc3a5c2 Ermal Lu?i
}
897
898
function lookup_gateway_interface_by_name($name) {
899
900 f040882c Renato Botelho
	$gateways_arr = return_gateways_array(false, true);
901 fe22a89b Ermal
	if (!empty($gateways_arr[$name])) {
902 be2a18bf Phil Davis
		$interfacegw = $gateways_arr[$name]['friendlyiface'];
903 fe22a89b Ermal
		return ($interfacegw);
904 f040882c Renato Botelho
	}
905 fe22a89b Ermal
906 f040882c Renato Botelho
	return (false);
907 6dc3a5c2 Ermal Lu?i
}
908
909 a2532739 Ermal Lu?i
function get_interface_gateway($interface, &$dynamic = false) {
910 5a5413bb Seth Mos
	global $config, $g;
911 6dc3a5c2 Ermal Lu?i
912 5a5413bb Seth Mos
	$gw = NULL;
913 6dc3a5c2 Ermal Lu?i
914 5a5413bb Seth Mos
	$gwcfg = $config['interfaces'][$interface];
915
	if (!empty($gwcfg['gateway']) && is_array($config['gateways']['gateway_item'])) {
916
		foreach($config['gateways']['gateway_item'] as $gateway) {
917
			if(($gateway['name'] == $gwcfg['gateway']) && (is_ipaddrv4($gateway['gateway']))) {
918
				$gw = $gateway['gateway'];
919 66a96e72 Ermal
				break;
920
			}
921 5a5413bb Seth Mos
		}
922 66a96e72 Ermal
	}
923 6dc3a5c2 Ermal Lu?i
924 5a5413bb Seth Mos
	// for dynamic interfaces we handle them through the $interface_router file.
925 2feb85af Seth Mos
	if (!is_ipaddrv4($gw) && !is_ipaddrv4($gwcfg['ipaddr'])) {
926 5a5413bb Seth Mos
		$realif = get_real_interface($interface);
927
		if (file_exists("{$g['tmp_path']}/{$realif}_router")) {
928
				$gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_router"), " \n");
929
			$dynamic = true;
930
		}
931
		if (file_exists("{$g['tmp_path']}/{$realif}_defaultgw"))
932
			$dynamic = "default";
933 f040882c Renato Botelho
934 5a5413bb Seth Mos
	}
935
936
	/* return gateway */
937
	return ($gw);
938
}
939
940
function get_interface_gateway_v6($interface, &$dynamic = false) {
941
	global $config, $g;
942 6dc3a5c2 Ermal Lu?i
943 5a5413bb Seth Mos
	$gw = NULL;
944
	$gwcfg = $config['interfaces'][$interface];
945 ed5c640d Seth Mos
	if (!empty($gwcfg['gatewayv6']) && is_array($config['gateways']['gateway_item'])) {
946 5a5413bb Seth Mos
		foreach($config['gateways']['gateway_item'] as $gateway) {
947 640b3a9a Seth Mos
			if(($gateway['name'] == $gwcfg['gatewayv6']) && (is_ipaddrv6($gateway['gateway']))) {
948 5a5413bb Seth Mos
				$gw = $gateway['gateway'];
949
				break;
950
			}
951
		}
952
	}
953
954
	// for dynamic interfaces we handle them through the $interface_router file.
955 2feb85af Seth Mos
	if (!is_ipaddrv6($gw) && !is_ipaddrv6($gwcfg['ipaddrv6'])) {
956 5a5413bb Seth Mos
			$realif = get_real_interface($interface);
957
			if (file_exists("{$g['tmp_path']}/{$realif}_routerv6")) {
958
				$gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_routerv6"), " \n");
959
				$dynamic = true;
960
			}
961
			if (file_exists("{$g['tmp_path']}/{$realif}_defaultgwv6"))
962
				$dynamic = "default";
963 f040882c Renato Botelho
964 5a5413bb Seth Mos
	}
965
	/* return gateway */
966
	return ($gw);
967 6dc3a5c2 Ermal Lu?i
}
968
969 318189b6 smos
/* Check a IP address against a gateway IP or name
970
 * to verify it's address family */
971
function validate_address_family($ipaddr, $gwname) {
972
	$v4ip = false;
973
	$v6ip = false;
974
	$v4gw = false;
975
	$v6gw = false;
976
977
	if(is_ipaddrv4($ipaddr))
978
		$v4ip = true;
979
	if(is_ipaddrv6($ipaddr))
980
		$v6ip = true;
981
	if(is_ipaddrv4($gwname))
982
		$v4gw = true;
983
	if(is_ipaddrv6($gwname))
984
		$v6gw = true;
985
986
	if($v4ip && $v4gw)
987
		return true;
988
	if($v6ip && $v6gw)
989
		return true;
990
991
	/* still no match, carry on, lookup gateways */
992
	if(is_ipaddrv4(lookup_gateway_ip_by_name($gwname)))
993
		$v4gw = true;
994
	if(is_ipaddrv6(lookup_gateway_ip_by_name($gwname)))
995
		$v6gw = true;
996 96cd928b smos
997
	$gw_array = return_gateways_array();
998
	if(is_array($gw_array[$gwname])) {
999
		switch($gw_array[$gwname]['ipprotocol']) {
1000
			case "inet":
1001
				$v4gw = true;
1002
				break;
1003
			case "inet6":
1004
				$v6gw = true;
1005
				break;
1006
		}
1007 748ff86f Seth Mos
	}
1008 318189b6 smos
1009
	if($v4ip && $v4gw)
1010
		return true;
1011
	if($v6ip && $v6gw)
1012
		return true;
1013 f040882c Renato Botelho
1014 318189b6 smos
	return false;
1015
}
1016
1017 cdb0df65 smos
/* check if a interface is part of a gateway group */
1018
function interface_gateway_group_member($interface) {
1019
	global $config;
1020 c447a9fe Ermal
1021
	if (is_array($config['gateways']['gateway_group']))
1022 cdb0df65 smos
		$groups = $config['gateways']['gateway_group'];
1023
	else
1024
		return false;
1025
1026 f040882c Renato Botelho
	$gateways_arr = return_gateways_array(false, true);
1027 cdb0df65 smos
	foreach($groups as $group) {
1028
		if(is_array($group['item'])) {
1029
			foreach($group['item'] as $item) {
1030
				$elements = explode("|", $item);
1031
				$gwname = $elements[0];
1032 c447a9fe Ermal
				if ($interface == $gateways_arr[$gwname]['interface']) {
1033
					unset($gateways_arr);
1034 017817c2 smos
					return true;
1035 c447a9fe Ermal
				}
1036 cdb0df65 smos
			}
1037
		}
1038
	}
1039 c447a9fe Ermal
	unset($gateways_arr);
1040
1041 cdb0df65 smos
	return false;
1042
}
1043 318189b6 smos
1044 58b1112f Ermal
function gateway_is_gwgroup_member($name) {
1045
	global $config;
1046
1047
	if (is_array($config['gateways']['gateway_group']))
1048
		$groups = $config['gateways']['gateway_group'];
1049
	else
1050
		return false;
1051
1052
	$members = array();
1053
	foreach($groups as $group) {
1054
		if (is_array($group['item'])) {
1055
			foreach($group['item'] as $item) {
1056
				$elements = explode("|", $item);
1057
				$gwname = $elements[0];
1058
				if ($name == $elements[0])
1059
					$members[] = $group['name'];
1060
			}
1061
		}
1062
	}
1063
1064
	return $members;
1065
}
1066 c832f6bf smos
?>