Project

General

Profile

Download (105 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	interfaces.inc
5
	Copyright (C) 2004-2008 Scott Ullrich
6
	Copyright (C) 2008-2009 Ermal Lu?i
7
	All rights reserved.
8

    
9
	function interfaces_wireless_configure is
10
	Copyright (C) 2005 Espen Johansen
11
	All rights reserved.
12

    
13
	originally part of m0n0wall (http://m0n0.ch/wall)
14
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
15
	All rights reserved.
16

    
17
	Redistribution and use in source and binary forms, with or without
18
	modification, are permitted provided that the following conditions are met:
19

    
20
	1. Redistributions of source code must retain the above copyright notices,
21
	   this list of conditions and the following disclaimer.
22

    
23
	2. Redistributions in binary form must reproduce the above copyright
24
	   notices, this list of conditions and the following disclaimer in the
25
	   documentation and/or other materials provided with the distribution.
26

    
27
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
28
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
	POSSIBILITY OF SUCH DAMAGE.
37

    
38
	pfSense_BUILDER_BINARIES:	/sbin/dhclient	/bin/sh	/usr/bin/grep	/usr/bin/xargs	/usr/bin/awk	/usr/local/sbin/choparp
39
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/sbin/route	/usr/sbin/ngctl	/usr/sbin/arp	/bin/kill	/usr/local/sbin/mpd5
40
	pfSense_MODULE:	interfaces
41

    
42
*/
43

    
44
/* include all configuration functions */
45
require_once("globals.inc");
46
require_once("cmd_chain.inc");
47

    
48
function interfaces_bring_up($interface) {
49
	if(!$interface) {
50
		log_error("interfaces_bring_up() was called but no variable defined.");
51
		log_error( "Backtrace: " . debug_backtrace() );
52
		return;
53
	}
54
	pfSense_interface_flags($interface, IFF_UP);
55
}
56

    
57
/*
58
 * Return the interface array
59
 */
60
function get_interface_arr($flush = false) {
61
        global $interface_arr_cache;
62

    
63
        /* If the cache doesn't exist, build it */
64
        if (!isset($interface_arr_cache) or $flush)
65
                $interface_arr_cache = explode(" ", trim(`/sbin/ifconfig -l`));
66

    
67
        return $interface_arr_cache;
68
}
69

    
70
/*
71
 * does_interface_exist($interface): return true or false if a interface is
72
 * detected.
73
 */
74
function does_interface_exist($interface) {
75
	global $config;
76
	
77
	if(!$interface)
78
		return false;
79

    
80
	$ints = get_interface_arr(true);
81
	if (in_array($interface, $ints))
82
		return true;
83
	else
84
		return false;
85
}
86

    
87
function interface_netgraph_needed($interface = "wan") {
88
	global $config;
89

    
90
	$found = false;
91
	if (!empty($config['pptpd']) &&
92
		$config['pptpd']['mode'] == "server")
93
		$found = true;
94
	if ($found == false && !empty($config['l2tp']) &&
95
		$config['l2tp']['mode'] == "server")
96
		$found = true;
97
	if ($found == false && is_array($config['pppoes']['pppoe'])) {
98
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
99
			if ($pppoe['mode'] != "server")
100
				continue;
101
			if ($pppoe['interface'] == $interface)
102
				$found = true;
103
				break;
104
		}
105
	}
106
	if ($found == false) {
107
		if (!empty($config['interfaces'][$interface])) {
108
			switch ($config['interfaces'][$interface]['ipaddr']) {
109
			case "ppp":
110
			case "pppoe":
111
			case "l2tp":
112
			case "pptp":
113
				$found = true;
114
				break;
115
			default:
116
				$found = false;
117
				break;
118
			}
119
		}
120
	}
121
	if ($found == false) {
122
		$realif = get_real_interface($interface);
123
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
124
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
125

    
126
/* This if block doesn't do anything. It can be deleted.
127
PPP interfaces are found above in the previous if ($found == false) block.
128
This block of code is only entered for OPTx interfaces that are configured for PPPoE modem access, so $realif != $ppp['if']
129

    
130
				if ($realif == $ppp['if']) {
131
					$found = true;
132
					break;
133
				}
134
*/			
135
				$ports = explode(',',$ppp['ports']);
136
				foreach($ports as $pid => $port){
137
					$port = get_real_interface($port);
138
					if ($realif == $port) {
139
						$found = true;
140
						break;
141
					}
142
					/* Find the parent interfaces of the vlans in the MLPPP configs 
143
					* there should be only one element in the array here 
144
					* -- this could be better . . . */
145
					$parent_if = get_parent_interface($port);
146
					if ($realif == $parent_if[0]) {
147
						$found = true;
148
						break;
149
					}
150
				}
151
			}
152
		}
153
	}
154
	
155
	if ($found == false) {
156
		$realif = get_real_interface($interface);
157
		pfSense_ngctl_detach("{$realif}:", $realif);
158
	}
159
	/* NOTE: We make sure for this on interface_ppps_configure()
160
	 *	no need to do it here agan.
161
	 *	else
162
	 *		pfSense_ngctl_attach(".", $realif);
163
	 */
164
}
165

    
166
function interfaces_loopback_configure() {
167
	if($g['booting'])
168
		echo "Configuring loopback interface...";
169
	pfSense_interface_setaddress("lo0", "127.0.0.1");
170
	interfaces_bring_up("lo0");
171
	if($g['booting'])
172
		echo "done.\n";
173
	return 0;
174
}
175

    
176
function interfaces_vlan_configure() {
177
	global $config, $g;
178
	if($g['booting'])
179
		echo "Configuring VLAN interfaces...";
180
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
181
		foreach ($config['vlans']['vlan'] as $vlan) {
182
			if(empty($vlan['vlanif']))
183
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
184
			/* XXX: Maybe we should report any errors?! */
185
			interface_vlan_configure($vlan);
186
		}
187
	}
188
	if($g['booting'])
189
		echo "done.\n";
190
}
191

    
192
function interface_vlan_configure(&$vlan) {
193
        global $config, $g;
194

    
195
	if (!is_array($vlan)) {
196
		log_error("VLAN: called with wrong options. Problems with config!");
197
		return;
198
	}
199
	$if = $vlan['if'];
200
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
201
	$tag = $vlan['tag'];
202

    
203
	if (empty($if)) {
204
		log_error("interface_vlan_confgure called with if undefined.");
205
		return;
206
	}
207

    
208
	/* make sure the parent interface is up */
209
	interfaces_bring_up($if);
210
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
211
	pfSense_interface_capabilities($if, IFCAP_VLAN_HWTAGGING|IFCAP_VLAN_MTU|IFCAP_VLAN_HWFILTER);
212

    
213
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
214
		interface_bring_down($vlanif, true);
215
	} else {
216
		$tmpvlanif = pfSense_interface_create("vlan");
217
		pfSense_interface_rename($tmpvlanif, $vlanif);
218
		pfSense_ngctl_name("{$tmpvlanif}:", $vlanif);
219
	}
220

    
221
	pfSense_vlan_create($vlanif, $if, $tag);
222

    
223
	interfaces_bring_up($vlanif);
224

    
225
	/* invalidate interface cache */
226
	get_interface_arr(true);
227

    
228
	/* XXX: ermal -- for now leave it here at the moment it does not hurt. */
229
	interfaces_bring_up($if);
230

    
231
	return $vlanif;
232
}
233

    
234
function interface_qinq_configure(&$vlan, $fd = NULL) {
235
        global $config, $g;
236

    
237
        if (!is_array($vlan)) {
238
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
239
                return;
240
        }
241

    
242
        $qinqif = $vlan['if'];
243
        $tag = $vlan['tag'];
244
        if(empty($qinqif)) {
245
                log_error("interface_qinq_confgure called with if undefined.\n");
246
                return;
247
        }
248
	$vlanif = interface_vlan_configure($vlan);
249

    
250
        if ($fd == NULL) {
251
                $exec = true;
252
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
253
        } else
254
                $exec = false;
255
        /* make sure the parent is converted to ng_vlan(4) and is up */
256
        interfaces_bring_up($qinqif);
257

    
258
        if (!empty($vlanif) && does_interface_exist($vlanif)) {
259
                fwrite($fd, "shutdown {$qinqif}qinq:\n");
260
                exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
261
                if (empty($result)) {
262
                        fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
263
                        fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
264
                        fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
265
                }
266
        } else {
267
                fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
268
                fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
269
                fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
270
        }
271

    
272
        /* invalidate interface cache */
273
        get_interface_arr(true);
274

    
275
        if (!stristr($qinqif, "vlan"))
276
                mwexec("/sbin/ifconfig {$qinqif} promisc\n");
277

    
278
        $macaddr = get_interface_mac($qinqif);
279
        if (!empty($vlan['members'])) {
280
                $members = explode(" ", $vlan['members']);
281
                foreach ($members as $qtag) {
282
                        $qinq = array();
283
                        $qinq['tag'] = $qtag;
284
                        $qinq['if'] = $vlanif;
285
                        interface_qinq2_configure($qinq, $fd, $macaddr);
286
                }
287
        }
288
        if ($exec == true) {
289
                fclose($fd);
290
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
291
        }
292

    
293
        interfaces_bring_up($qinqif);
294
        if (!empty($vlan['members'])) {
295
                $members = explode(" ", $vlan['members']);
296
                foreach ($members as $qif)
297
                        interfaces_bring_up("{$vlanif}_{$qif}");
298
        }
299

    
300
        return $vlanif;
301
}
302

    
303
function interfaces_qinq_configure() {
304
	global $config, $g;
305
	if($g['booting'])
306
		echo "Configuring QinQ interfaces...";
307
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
308
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
309
			/* XXX: Maybe we should report any errors?! */
310
			interface_qinq_configure($qinq);
311
		}
312
	}
313
	if($g['booting'])
314
		echo "done.\n";
315
}
316

    
317
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
318
        global $config, $g;
319

    
320
        if (!is_array($qinq)) {
321
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
322
                return;
323
        }
324

    
325
        $if = $qinq['if'];
326
        $tag = $qinq['tag'];
327
        $vlanif = "{$if}_{$tag}";
328
        if(empty($if)) {
329
                log_error("interface_qinq_confgure called with if undefined.\n");
330
                return;
331
        }
332

    
333
        fwrite($fd, "shutdown {$if}h{$tag}:\n");
334
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
335
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
336
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
337
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
338
        fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
339

    
340
        /* invalidate interface cache */
341
        get_interface_arr(true);
342

    
343
        return $vlanif;
344
}
345

    
346
function interfaces_create_wireless_clones() {
347
	global $config;
348

    
349
	if($g['booting'])
350
		echo "Creating other wireless clone interfaces...";
351
	if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
352
		foreach ($config['wireless']['clone'] as $clone) {
353
			if(empty($clone['cloneif']))
354
				continue;
355
			if(does_interface_exist($clone['cloneif']))
356
				continue;
357
			/* XXX: Maybe we should report any errors?! */
358
			if(interface_wireless_clone($clone['cloneif'], $clone))
359
				if($g['booting'])
360
					echo " " . $clone['cloneif'];
361
		}
362
	}
363
	if($g['booting'])
364
		echo " done.\n";
365
}
366

    
367
function interfaces_bridge_configure() {
368
        global $config;
369

    
370
        $i = 0;
371
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
372
                foreach ($config['bridges']['bridged'] as $bridge) {
373
                        if(empty($bridge['bridgeif']))
374
                                $bridge['bridgeif'] = "bridge{$i}";
375
                        /* XXX: Maybe we should report any errors?! */
376
                        interface_bridge_configure($bridge);
377
                        $i++;
378
                }
379
        }
380
}
381

    
382
function interface_bridge_configure(&$bridge) {
383
	global $config, $g;
384

    
385
	if (!is_array($bridge))
386
	        return -1;
387

    
388
	if (empty($bridge['members'])) {
389
		log_error("No members found on {$bridge['bridgeif']}");
390
		return -1;
391
	}
392

    
393
	$members = explode(',', $bridge['members']);
394
	if (!count($members))
395
		return -1;
396

    
397
	$checklist = get_configured_interface_list();
398

    
399
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
400
		pfSense_interface_destroy($bridge['bridgeif']);
401
		pfSense_interface_create($bridge['bridgeif']);
402
		$bridgeif = $bridge['bridgeif'];
403
	} else
404
		$bridgeif = pfSense_interface_create("bridge");
405

    
406
	/* Calculate smaller mtu and enforce it */
407
	$smallermtu = 0;
408
	$commonrx = true;
409
	$commontx = true;
410
	foreach ($members as $member) {
411
		$realif = get_real_interface($member);
412
		$opts = pfSense_get_interface_addresses($realif);
413
		$mtu = $opts['mtu'];
414
		if (!isset($opts['encaps']['txcsum']))
415
			$commontx = false;
416
		if (!isset($opts['encaps']['rxcsum']))
417
			$commonrx = false;
418
		if (!isset($opts['encaps']['tso4']))
419
			$commontso4 = false;
420
		if (!isset($opts['encaps']['tso6']))
421
			$commontso6 = false;
422
		if (!isset($opts['encaps']['lro']))
423
			$commonlro = false;
424
		if ($smallermtu == 0 && !empty($mtu))
425
			$smallermtu = $mtu;
426
		else if (!empty($mtu) && $mtu < $smallermtu)
427
			$smallermtu = $mtu;
428
	}
429
	 
430
	/* Just in case anything is not working well */
431
	if ($smallermtu == 0)
432
		$smallermtu = 1500; 
433

    
434
	$flags = 0;
435
	if ($commonrx === false)
436
		$flags |= IFCAP_RXCSUM;
437
	if ($commontx === false)
438
		$flags |= IFCAP_TXCSUM;
439
	if ($commontso4 === false)
440
		$flags |= IFCAP_TSO4;
441
	if ($commontso6 === false)
442
		$flags |= IFCAP_TSO6;
443
	if ($commonlro === false)
444
		$flags |= IFCAP_LRO;
445
		
446
	/* Add interfaces to bridge */
447
	foreach ($members as $member) {
448
		if (!array_key_exists($member, $checklist))
449
			continue;
450
		$realif1 = get_real_interface($member);
451
		$realif =  escapeshellarg($realif1);
452
		if (!$realif) {
453
			log_error("realif not defined in interfaces bridge - up");
454
			continue;
455
		}
456
		/* make sure the parent interface is up */
457
		pfSense_interface_mtu($realif1, $smallermtu);
458
		pfSense_interface_capabilities($realif1, -$flags);
459
		interfaces_bring_up($realif1);
460
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
461
	}
462

    
463
	if (isset($bridge['enablestp'])) {
464
		/* Choose spanning tree proto */
465
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
466
		
467
		if (!empty($bridge['stp'])) {
468
			$stpifs = explode(',', $bridge['stp']);
469
			foreach ($stpifs as $stpif) {
470
				$realif = get_real_interface($stpif);
471
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
472
			}
473
		}
474
		if (!empty($bridge['maxage']))
475
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
476
		if (!empty($brige['fwdelay']))
477
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
478
		if (!empty($brige['hellotime']))
479
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
480
		if (!empty($brige['priority']))
481
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
482
		if (!empty($brige['holdcount']))
483
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
484
		if (!empty($bridge['ifpriority'])) {
485
			$pconfig = explode(",", $bridge['ifpriority']);
486
			$ifpriority = array();
487
			foreach ($pconfig as $cfg) {
488
				$embcfg = explode(":", $cfg);
489
				foreach ($embcfg as $key => $value)
490
					$ifpriority[$key] = $value;
491
			}
492
			foreach ($ifpriority as $key => $value) {
493
				$realif = get_real_interface($key);
494
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
495
			}
496
		}
497
		if (!empty($bridge['ifpathcost'])) {
498
			$pconfig = explode(",", $bridges['ifpathcost']);
499
			$ifpathcost = array();
500
			foreach ($pconfig as $cfg) {
501
				$embcfg = explode(":", $cfg);
502
				foreach ($embcfg as $key => $value)
503
					$ifpathcost[$key] = $value;
504
			}
505
			foreach ($ifpathcost as $key => $value) {
506
                        	$realif = get_real_interface($key);
507
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
508
                	}
509
		}
510
	}
511

    
512
	if ($bridge['maxaddr'] <> "")
513
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
514
        if ($bridge['timeout'] <> "")
515
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
516
        if ($bridge['span'] <> "") {
517
		$realif = get_real_interface($bridge['span']);
518
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
519
	}
520
	if (!empty($bridge['edge'])) {
521
        	$edgeifs = explode(',', $bridge['edge']);
522
        	foreach ($edgeifs as $edgeif) {
523
			$realif = get_real_interface($edgeif);
524
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
525
        	}
526
	}
527
	if (!empty($bridge['autoedge'])) {
528
        	$edgeifs = explode(',', $bridge['autoedge']);
529
        	foreach ($edgeifs as $edgeif) {
530
                	$realif = get_real_interface($edgeif);
531
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
532
        	}
533
	}
534
	if (!empty($bridge['ptp'])) {
535
        	$ptpifs = explode(',', $bridge['ptp']);
536
        	foreach ($ptpifs as $ptpif) {
537
                	$realif = get_real_interface($ptpif);
538
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
539
        	}
540
	}
541
	if (!empty($bridge['autoptp'])) {
542
        	$ptpifs = explode(',', $bridge['autoptp']);
543
        	foreach ($ptpifs as $ptpif) {
544
                	$realif = get_real_interface($ptpif);
545
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
546
        	}
547
	}
548
	if (!empty($bridge['static'])) {
549
        	$stickyifs = explode(',', $bridge['static']);
550
        	foreach ($stickyifs as $stickyif) {
551
                	$realif = get_real_interface($stickyif);
552
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
553
        	}
554
	}
555
	if (!empty($bridge['private'])) {
556
        	$privateifs = explode(',', $bridge['private']);
557
        	foreach ($privateifs as $privateif) {
558
                	$realif = get_real_interface($privateif);
559
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
560
        	}
561
	}
562

    
563
	if($bridgeif)
564
		interfaces_bring_up($bridgeif);	
565
	else 
566
		log_error("bridgeif not defined -- could not bring interface up");
567

    
568
	return $bridgeif;
569
}
570

    
571
function interface_bridge_add_member($bridgeif, $interface) {
572

    
573
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
574
		return;
575

    
576
	$mtu = get_interface_mtu($brigeif);
577
	$mtum = get_interface_mtu($interface);
578
	
579
	if ($mtu != $mtum)
580
		pfSense_interface_mtu($interface, $mtu);
581

    
582
	$options = pfSense_get_interface_addresses($bridgeif);
583
	$flags = 0;
584
	if (!isset($options['encaps']['txcsum']))
585
		$flags |= IFCAP_TXCSUM;
586

    
587
	if (!isset($options['encaps']['rxcsum']))
588
		$flags |= IFCAP_RXCSUM;
589

    
590
	pfSense_interface_capabilities($interface, -$flags);
591

    
592
	interfaces_bring_up($interface);
593
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
594
}
595

    
596
function interfaces_lagg_configure() 
597
{
598
        global $config, $g;
599
		if($g['booting']) 
600
			echo "Configuring LAGG interfaces...";
601
        $i = 0;
602
		if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
603
			foreach ($config['laggs']['lagg'] as $lagg) {
604
				if(empty($lagg['laggif']))
605
					$lagg['laggif'] = "lagg{$i}";
606
				/* XXX: Maybe we should report any errors?! */
607
				interface_lagg_configure($lagg);
608
				$i++;
609
			}
610
		}
611
		if($g['booting']) 
612
			echo "done.\n";
613
}
614

    
615
function interface_lagg_configure(&$lagg) {
616
        global $config, $g;
617

    
618
        if (!is_array($lagg))
619
		return -1;
620

    
621
	$members = explode(',', $lagg['members']);
622
	if (!count($members))
623
		return -1;
624
	
625
	$checklist = get_interface_list();
626

    
627
	if ($g['booting'] || !(empty($lagg['laggif']))) {
628
		pfSense_interface_destroy($lagg['laggif']);
629
		pfSense_interface_create($lagg['laggif']);
630
                $laggif = $lagg['laggif'];
631
        } else
632
		$laggif = pfSense_interface_create("lagg");
633

    
634
	/* Calculate smaller mtu and enforce it */
635
        $smallermtu = 0;
636
        foreach ($members as $member) {
637
		$opts = pfSense_get_interface_addresses($member);
638
                $mtu = $opts['mtu'];
639
		if (!isset($opts['encaps']['txcsum']))
640
                        $commontx = false;
641
                if (!isset($opts['encaps']['rxcsum']))
642
                        $commonrx = false;
643
		if (!isset($opts['encaps']['tso4']))
644
			$commontso4 = false;
645
		if (!isset($opts['encaps']['tso6']))
646
			$commontso6 = false;
647
		if (!isset($opts['encaps']['lro']))
648
			$commonlro = false;
649
		if ($smallermtu == 0 && !empty($mtu))
650
			$smallermtu = $mtu;
651
                else if (!empty($mtu) && $mtu < $smallermtu)
652
                        $smallermtu = $mtu;
653
        }
654

    
655
	/* Just in case anything is not working well */
656
        if ($smallermtu == 0)
657
                $smallermtu = 1500;
658

    
659
	$flags = 0;
660
        if ($commonrx === false)
661
                $flags |= IFCAP_RXCSUM;
662
        if ($commontx === false)
663
                $flags |= IFCAP_TXCSUM;
664
	if ($commontso4 === false)
665
                $flags |= IFCAP_TSO4;
666
        if ($commontso6 === false)
667
                $flags |= IFCAP_TSO6;
668
        if ($commonlro === false)
669
                $flags |= IFCAP_LRO;
670

    
671
	foreach ($members as $member) {
672
		if (!array_key_exists($member, $checklist))
673
			continue;
674
		/* make sure the parent interface is up */
675
		pfSense_interface_mtu($member, $smallermtu);
676
		pfSense_interface_capabilities($member, -$flags);
677
		interfaces_bring_up($member);
678
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
679
	}
680
	
681
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
682

    
683
	interfaces_bring_up($laggif);
684

    
685
	return $laggif;
686
}
687

    
688
function interfaces_gre_configure() {
689
        global $config;
690

    
691
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
692
                foreach ($config['gres']['gre'] as $i => $gre) {
693
                        if(empty($gre['greif']))
694
                                $gre['greif'] = "gre{$i}";
695
                        /* XXX: Maybe we should report any errors?! */
696
                        interface_gre_configure($gre);
697
                }
698
        }
699
}
700

    
701
/* NOTE: $grekey is not used but useful for passing this function to array_walk. */
702
function interface_gre_configure(&$gre, $grekey = "") {
703
        global $config, $g;
704

    
705
	if (!is_array($gre))
706
		return -1;
707

    
708
	$realif = get_real_interface($gre['if']);
709
	$realifip = get_interface_ip($gre['if']);
710

    
711
	/* make sure the parent interface is up */
712
	interfaces_bring_up($realif);
713

    
714
	if ($g['booting'] || !(empty($gre['greif']))) {
715
		pfSense_interface_destroy($gre['greif']);
716
		pfSense_interface_create($gre['greif']);
717
		$greif = $gre['greif'];
718
	} else
719
		$greif = pfSense_interface_create("gre");
720

    
721
	/* Do not change the order here for more see gre(4) NOTES section. */
722
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
723
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
724
	if (isset($gre['link0']) && $gre['link0'])
725
		pfSense_interface_flags($greif, IFF_LINK0);
726
	if (isset($gre['link1']) && $gre['link1'])
727
		pfSense_interface_flags($greif, IFF_LINK1);
728
	if (isset($gre['link2']) && $gre['link2'])
729
		pfSense_interface_flags($greif, IFF_LINK2);
730

    
731
	if($greif)
732
		interfaces_bring_up($greif);
733
	else 
734
		log_error("Could not bring greif up -- variable not defined.");
735

    
736
	if (isset($gre['link1']) && $gre['link1'])
737
		mwexec("/sbin/route add {$gre['tunnel-remote-addr']}/{$gre['tunnel-remote-net']} {$gre['tunnel-local-addr']}");
738
	file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']);
739

    
740
	return $greif;
741
}
742

    
743
function interfaces_gif_configure() {
744
	global $config;
745

    
746
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
747
		foreach ($config['gifs']['gif'] as $i => $gif) {
748
			if(empty($gif['gifif']))
749
				$gre['gifif'] = "gif{$i}";
750
			/* XXX: Maybe we should report any errors?! */
751
			interface_gif_configure($gif);
752
		}
753
	}
754
}
755

    
756
/* NOTE: $gifkey is not used but useful for passing this function to array_walk. */
757
function interface_gif_configure(&$gif, $gifkey = "") {
758
	global $config, $g;
759

    
760
	if (!is_array($gif))
761
		return -1;
762

    
763
	$realif = get_real_interface($gif['if']);
764
	$realifip = get_interface_ip($gif['if']);
765

    
766
	/* make sure the parent interface is up */
767
	if($realif)
768
		interfaces_bring_up($realif);
769
	else 
770
		log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
771

    
772
	if ($g['booting'] || !(empty($gif['gifif']))) {
773
		pfSense_interface_destroy($gif['gifif']);
774
		pfSense_interface_create($gif['gifif']);
775
		$gifif = $gif['gifif'];
776
	} else
777
		$gifif = pfSense_interface_create("gif");
778

    
779
	/* Do not change the order here for more see gif(4) NOTES section. */
780
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
781
	mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
782
	if (isset($gif['link0']) && $gif['link0'])
783
		pfSense_interface_flags($gifif, IFF_LINK0);
784
	if (isset($gif['link1']) && $gif['link1'])
785
		pfSense_interface_flags($gifif, IFF_LINK1);
786
	if($gifif)
787
		interfaces_bring_up($gifif);
788
	else
789
		log_error("could not bring gifif up -- variable not defined");
790

    
791
	/* XXX: Needed?! */
792
	//mwexec("/sbin/route add {$gif['tunnel-remote-addr']}/{$gif['tunnel-remote-net']} -iface {$gifif}");
793
	file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']);
794

    
795
	return $gifif;
796
}
797

    
798
function interfaces_configure() {
799
	global $config, $g;
800

    
801
	/* Set up our loopback interface */
802
	interfaces_loopback_configure();
803

    
804
	/* set up LAGG virtual interfaces */
805
	interfaces_lagg_configure();
806

    
807
	/* set up VLAN virtual interfaces */
808
	interfaces_vlan_configure();
809

    
810
	interfaces_qinq_configure();
811

    
812
	$iflist = get_configured_interface_with_descr();
813
	$delayed_list = array();
814
	$bridge_list = array();
815
	
816
	/* This is needed to speedup interfaces on bootup. */
817
	$reload = false;
818
	if ($g['booting'])
819
		$reload = true;
820

    
821
	foreach($iflist as $if => $ifname) {
822
		$realif = $config['interfaces'][$if]['if'];
823
		if (strstr($realif, "bridge")) 
824
			$bridge_list[$if] = $ifname;
825
		else if (strstr($realif, "gre"))
826
			$delayed_list[$if] = $ifname;
827
		else if (strstr($realif, "gif"))
828
			$delayed_list[$if] = $ifname;
829
		else if (strstr($realif, "ovpn")) {
830
			//echo "Delaying OpenVPN interface configuration...done.\n";
831
			continue;
832
		} else {
833
			if ($g['booting'])
834
				echo "Configuring {$ifname} interface...";
835
			if($g['debug'])
836
				log_error("Configuring {$ifname}");
837
			interface_configure($if, $reload);
838
			if ($g['booting']) 
839
				echo "done.\n";
840
		}
841
	}
842

    
843
	/* create the unconfigured wireless clones */
844
	interfaces_create_wireless_clones();
845

    
846
	/* set up GRE virtual interfaces */
847
	interfaces_gre_configure();
848

    
849
	/* set up GIF virtual interfaces */
850
	interfaces_gif_configure();
851
	
852
	foreach ($delayed_list as $if => $ifname) {
853
		if ($g['booting'])
854
			echo "Configuring {$ifname} interface...";
855
        	if ($g['debug'])
856
        		log_error("Configuring {$ifname}");
857

    
858
		interface_configure($if, $reload);
859

    
860
		if ($g['booting'])
861
			echo "done.\n";
862
	}
863

    
864
	/* set up BRIDGe virtual interfaces */
865
	interfaces_bridge_configure();
866

    
867
	foreach ($bridge_list as $if => $ifname) {
868
		if ($g['booting'])
869
			echo "Configuring {$ifname} interface...";
870
		if($g['debug'])
871
			log_error("Configuring {$ifname}");
872

    
873
		interface_configure($if, $reload);
874

    
875
		if ($g['booting'])
876
			echo "done.\n";
877
	}
878

    
879
	/* bring up vip interfaces */
880
	interfaces_vips_configure();
881

    
882
	/* configure interface groups */
883
	interfaces_group_setup();
884

    
885
	if (!$g['booting']) {
886
		/* reconfigure static routes (kernel may have deleted them) */
887
		system_routing_configure();
888

    
889
		/* reload IPsec tunnels */
890
		vpn_ipsec_configure();
891

    
892
		/* reload dhcpd (interface enabled/disabled status may have changed) */
893
		services_dhcpd_configure();
894

    
895
		/* restart dnsmasq */
896
		services_dnsmasq_configure();
897

    
898
		/* reload captive portal */
899
		captiveportal_init_rules();
900
	}
901

    
902
	return 0;
903
}
904

    
905
function interface_reconfigure($interface = "wan") {
906
	interface_bring_down($interface);
907
	interface_configure($interface, true);
908
}
909

    
910
function interface_vip_bring_down($vip) {
911
	global $g;
912

    
913
	switch ($vip['mode']) {
914
	case "proxyarp":
915
		$vipif = get_real_interface($vip['interface']);
916
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
917
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
918
		break;
919
	case "ipalias":
920
		$vipif = get_real_interface($vip['interface']);
921
		if(does_interface_exist($vipif))
922
			pfSense_interface_deladdress($vipif, $vip['subnet']);
923
		break;
924
	case "carp":
925
		$vipif = "vip" . $vip['vhid'];
926
		if(does_interface_exist($vipif)) 
927
			pfSense_interface_destroy($vipif);
928
		break;
929
	case "carpdev-dhcp":
930
		$vipif = "vip" . $vip['vhid'];
931
		if(does_interface_exist($vipif)) 
932
			pfSense_interface_destroy($vipif);
933
		break;
934
	}
935
}
936

    
937
function interface_bring_down($interface = "wan", $destroy = false) {
938
	global $config, $g;
939

    
940
	if (!isset($config['interfaces'][$interface]))
941
		return; 
942

    
943
	$ifcfg = $config['interfaces'][$interface];
944

    
945
	$realif = get_real_interface($interface);
946

    
947
	switch ($ifcfg['ipaddr']) {
948
	case "ppp":
949
	case "pppoe":
950
	case "pptp":
951
	case "l2tp":
952
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
953
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
954
				if ($realif == $ppp['if']) {
955
					if (isset($ppp['ondemand']) && !$destroy){
956
						send_event("interface reconfigure {$interface}");
957
						break;
958
					}
959
					if (file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid")) {
960
						killbypid("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid");
961
						sleep(2);
962
					}
963
					unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
964
					break;
965
				}
966
			}
967
		}
968
		break;
969
	case "carpdev-dhcp":
970
		/* 
971
		 * NB: When carpdev gets enabled it would be better to be handled as all
972
		 *	   other interfaces! 
973
		 */
974
	case "dhcp":
975
		$pid = find_dhclient_process($realif);
976
		if($pid)
977
			mwexec("/bin/kill {$pid}");
978
		sleep(1);
979
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
980
		if(does_interface_exist("$realif")) {
981
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
982
			if ($destroy == true)
983
				pfSense_interface_flags($realif, -IFF_UP);
984
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
985
		}
986
		break;
987
	default:
988
		if(does_interface_exist("$realif")) {
989
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
990
			if ($destroy == true)
991
				pfSense_interface_flags($realif, -IFF_UP);
992
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
993
		}
994
		break;
995
	}
996

    
997
	/* remove interface up file if it exists */
998
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
999
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
1000
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
1001
	unlink_if_exists("{$g['varetc_path']}/nameserver_{$realif}");
1002
	unlink_if_exists("{$g['varetc_path']}/searchdomain_{$realif}");
1003
	
1004
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
1005
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
1006
	if (is_array($ifcfg['wireless'])) {
1007
		mwexec(kill_hostapd($realif));
1008
		mwexec(kill_wpasupplicant($realif));
1009
	}
1010

    
1011
	if ($destroy == true) {
1012
		if (preg_match("/^vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
1013
			pfSense_interface_destroy($realif);
1014
	}	
1015

    
1016
	return;
1017
}
1018

    
1019
function interfaces_ptpid_used($ptpid) {
1020
	global $config;
1021

    
1022
	if (is_array($config['ppps']['ppp']))
1023
		foreach ($config['ppps']['ppp'] as & $settings)
1024
			if ($ptpid == $settings['ptpid'])
1025
				return true;
1026

    
1027
	return false;
1028
}
1029

    
1030
function interfaces_ptpid_next() {
1031

    
1032
	$ptpid = 0;
1033
	while(interfaces_ptpid_used($ptpid))
1034
		$ptpid++;
1035

    
1036
	return $ptpid;
1037
}
1038

    
1039
function getMPDCRONSettings($pppif_) {
1040
	global $config;
1041
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
1042
	if (is_array($config['cron']['item'])) {
1043
		for ($i = 0; $i < count($config['cron']['item']); $i++) {
1044
			$item = $config['cron']['item'][$i];
1045
			if (strpos($item['command'], $cron_cmd_file.$pppif_) !== false) {
1046
				return array("ID" => $i, "ITEM" => $item);
1047
			}
1048
		}
1049
	}
1050
	return NULL;
1051
}
1052

    
1053
function handle_pppoe_reset($post_array) {
1054
	global $config, $g;
1055

    
1056
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
1057

    
1058
	$pppif = $post_array['type'].$post_array['ptpid'];
1059
	if (!is_array($config['cron']['item'])) 
1060
		$config['cron']['item'] = array(); 
1061
	$itemhash = getMPDCRONSettings($pppif);
1062
	$item = $itemhash['ITEM'];
1063
	
1064
	// reset cron items if necessary and return
1065
	if (empty($post_array['pppoe-reset-type'])) {
1066
		if (isset($item))
1067
			unset($config['cron']['item'][$itemhash['ID']]);
1068
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
1069
		return;
1070
	}
1071

    
1072
	if (empty($item)) 
1073
		$item = array();
1074
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
1075
		$item['minute'] = $post_array['pppoe_resetminute'];
1076
		$item['hour'] = $post_array['pppoe_resethour'];
1077
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
1078
			$date = explode("/", $post_array['pppoe_resetdate']);
1079
			$item['mday'] = $date[1];
1080
			$item['month'] = $date[0];
1081
		} else {
1082
			$item['mday'] = "*";
1083
			$item['month'] = "*";
1084
		}
1085
		$item['wday'] = "*";
1086
		$item['who'] = "root";
1087
		$item['command'] = $cron_cmd_file.$pppif;
1088
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
1089
		switch ($post_array['pppoe_pr_preset_val']) {
1090
			case "monthly":
1091
				$item['minute'] = "0";
1092
				$item['hour'] = "0";
1093
				$item['mday'] = "1";
1094
				$item['month'] = "*";
1095
				$item['wday'] = "*";
1096
				$item['who'] = "root";
1097
				$item['command'] = $cron_cmd_file.$pppif;
1098
				break;
1099
	        case "weekly":
1100
				$item['minute'] = "0";
1101
				$item['hour'] = "0";
1102
				$item['mday'] = "*";
1103
				$item['month'] = "*";
1104
				$item['wday'] = "0";
1105
				$item['who'] = "root";
1106
				$item['command'] = $cron_cmd_file.$pppif;
1107
				break;
1108
			case "daily":
1109
				$item['minute'] = "0";
1110
				$item['hour'] = "0";
1111
				$item['mday'] = "*";
1112
				$item['month'] = "*";
1113
				$item['wday'] = "*";
1114
				$item['who'] = "root";
1115
				$item['command'] = $cron_cmd_file.$pppif;
1116
				break;
1117
			case "hourly":
1118
				$item['minute'] = "0";
1119
				$item['hour'] = "*";
1120
				$item['mday'] = "*";
1121
				$item['month'] = "*";
1122
				$item['wday'] = "*";
1123
				$item['who'] = "root";
1124
				$item['command'] = $cron_cmd_file.$pppif;
1125
				break;
1126
		} // end switch
1127
	} else {
1128
		/* test whether a cron item exists and unset() it if necessary */
1129
		$itemhash = getMPDCRONSettings($pppif);
1130
		$item = $itemhash['ITEM'];
1131
		if (isset($item))
1132
			unset($config['cron']['item'][$itemhash['ID']]); 
1133
	}// end if
1134
	if (isset($itemhash['ID'])) 
1135
		$config['cron']['item'][$itemhash['ID']] = $item;
1136
	else 
1137
		$config['cron']['item'][] = $item;
1138
}
1139

    
1140
/*	This function can configure PPPoE, MLPPP (PPPoE), PPTP.
1141
*	It writes the mpd config file to /var/etc every time the link is opened.
1142
*/
1143

    
1144
function interface_ppps_configure($interface) {
1145
	global $config, $g;
1146
	
1147
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1148
	if(!is_dir("/var/spool/lock")) {
1149
		exec("/bin/mkdir -p /var/spool/lock");
1150
		exec("/bin/chmod a+rw /var/spool/lock/.");
1151
	}
1152
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files	
1153
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1154
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1155
		
1156
	$ifcfg = $config['interfaces'][$interface];
1157
	if (!isset($ifcfg['enable']))
1158
		return 0;
1159
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1160
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1161
			if ($ifcfg['if'] == $ppp['if'])
1162
				break;
1163
		}
1164
	}
1165
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1166
		log_error("Can't find PPP config for {$ifcfg['if']} in interface_ppps_configure().");
1167
		return 0;
1168
	}
1169
	$pppif = $ifcfg['if'];
1170
	if ($ppp['type'] == "ppp")
1171
		$type = "modem";
1172
	else
1173
		$type = $ppp['type'];
1174
	$upper_type = strtoupper($ppp['type']);	
1175
	
1176
	if($g['booting']) {
1177
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1178
		echo "starting {$pppif} link...";
1179
		// Do not re-configure the interface if we are booting and it's already been started
1180
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1181
			return 0;
1182
	}
1183
	
1184
	$ports = explode(',',$ppp['ports']);
1185
	if ($type != "modem") {
1186
		foreach ($ports as $pid => $port)
1187
			$ports[$pid] = get_real_interface($port);
1188
	}
1189
	$localips = explode(',',$ppp['localip']);
1190
	$gateways = explode(',',$ppp['gateway']);
1191
	$subnets = explode(',',$ppp['subnet']);
1192
	
1193
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1194
	to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1195
	*/
1196
	foreach($ports as $pid => $port){
1197
		switch ($ppp['type']) {
1198
			case "pppoe": 
1199
				/* Bring the parent interface up */
1200
				interfaces_bring_up($port);
1201
				pfSense_ngctl_attach(".", $port);
1202
				break;
1203
			case "pptp":
1204
			case "l2tp":
1205
				/* configure interface */
1206
				if(is_ipaddr($localips[$pid])){
1207
					// Manually configure interface IP/subnet
1208
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1209
					interfaces_bring_up($port);
1210
				} else if (empty($localips[$pid]))
1211
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1212
				
1213
				if(!is_ipaddr($localips[$pid])){
1214
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure.");
1215
					return 0;
1216
				}
1217
				/* XXX: This needs to go away soon! [It's commented out!] */
1218
				/* Configure the gateway (remote IP ) */
1219
				if (!$g['booting'] && !is_ipaddr($gateways[$pid]) && is_hostname($gateways[$pid])) {
1220
					/* XXX: Fix later 
1221
					$gateways[$pid] = gethostbyname($gateways[$pid]);
1222
					if(!is_ipaddr($gateways[$pid])) {
1223
						log_error("Could not get a valid Gateway IP from {$port} via DNS in interfaces_ppps_configure.");
1224
						return 0;
1225
					}
1226
					*/
1227
				}
1228
				if(!is_ipaddr($gateways[$pid])){
1229
					log_error("Could not get a PPTP/L2TP Remote IP address from {$dhcp_gateway} for {$gway} in interfaces_ppps_configure.");
1230
					return 0;
1231
				}
1232
				pfSense_ngctl_attach(".", $port);
1233
				break;
1234
			case "ppp":
1235
				if (!file_exists("{$port}")) {
1236
					log_error("Device {$port} does not exist. PPP link cannot start without the modem device.");
1237
					return 0;
1238
				}
1239
				break;
1240
			default:
1241
				log_error("Unkown {$type} configured as ppp interface.");
1242
				break;
1243
		}
1244
	}
1245
	
1246
	if (is_array($ports) && count($ports) > 1)
1247
		$multilink = "enable";
1248
	else
1249
		$multilink = "disable";
1250
	
1251
	if ($type == "modem"){
1252
		if (is_ipaddr($ppp['localip']))
1253
			$localip = $ppp['localip'];
1254
		else
1255
			$localip = '0.0.0.0';
1256

    
1257
		if (is_ipaddr($ppp['gateway']))
1258
			$gateway = $ppp['gateway'];
1259
		else
1260
			$gateway = "10.64.64.{$pppid}";
1261
		$ranges = "{$localip}/0 {$gateway}/0";
1262
		
1263
		if (empty($ppp['apnum']))	
1264
			$ppp['apnum'] = 1;
1265
	} else
1266
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1267

    
1268
	if (isset($ppp['ondemand'])) 
1269
		$ondemand = "enable";
1270
	else
1271
		$ondemand = "disable";
1272
	if (!isset($ppp['idletimeout']))
1273
		$ppp['idletimeout'] = 0;
1274

    
1275
	if (empty($ppp['username']) && $type == "modem"){
1276
		$ppp['username'] = "user";
1277
		$ppp['password'] = "none";
1278
	}
1279
	if (empty($ppp['password']) && $type == "modem")
1280
		$passwd = "none";
1281
	else
1282
		$passwd = base64_decode($ppp['password']);
1283

    
1284
	$bandwidths = explode(',',$ppp['bandwidth']);
1285
	$mtus = explode(',',$ppp['mtu']);
1286
	$mrus = explode(',',$ppp['mru']);
1287

    
1288
	if (isset($ppp['mrru']))
1289
		$mrrus = explode(',',$ppp['mrru']);
1290

    
1291
	// Construct the mpd.conf file
1292
	$mpdconf = <<<EOD
1293
startup:
1294
	# configure the console
1295
	set console close
1296
	# configure the web server
1297
	set web close
1298

    
1299
default:
1300
{$ppp['type']}client:
1301
	create bundle static {$interface}
1302
	set iface name {$pppif}
1303

    
1304
EOD;
1305
	$setdefaultgw = false;
1306
	$founddefaultgw = false;
1307
	if (is_array($config['gateways']['gateway_item'])) {
1308
		foreach($config['gateways']['gateway_item'] as $gateway) {
1309
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1310
				$setdefaultgw = true;
1311
				break;
1312
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1313
				$founddefaultgw = true;
1314
				break;
1315
			}
1316
		}
1317
	}
1318
	
1319
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1320
		$setdefaultgw = true;
1321
		$mpdconf .= <<<EOD
1322
	set iface route default
1323

    
1324
EOD;
1325
	}
1326
	$mpdconf .= <<<EOD
1327
	set iface {$ondemand} on-demand
1328
	set iface idle {$ppp['idletimeout']}
1329

    
1330
EOD;
1331

    
1332
	if (isset($ppp['ondemand']))
1333
		$mpdconf .= <<<EOD
1334
	set iface addrs 10.10.1.1 10.10.1.2
1335

    
1336
EOD;
1337
	
1338
	if (isset($ppp['tcpmssfix']))
1339
		$tcpmss = "disable";
1340
	else
1341
		$tcpmss = "enable";
1342
		$mpdconf .= <<<EOD
1343
	set iface {$tcpmss} tcpmssfix
1344

    
1345
EOD;
1346

    
1347
	$mpdconf .= <<<EOD
1348
	set iface up-script /usr/local/sbin/ppp-linkup
1349
	set iface down-script /usr/local/sbin/ppp-linkdown
1350
	set ipcp ranges {$ranges}
1351

    
1352
EOD;
1353
	if (isset($ppp['vjcomp']))
1354
		$mpdconf .= <<<EOD
1355
	set ipcp no vjcomp
1356

    
1357
EOD;
1358

    
1359
	if (isset($config['system']['dnsallowoverride']))
1360
		$mpdconf .= <<<EOD
1361
	set ipcp enable req-pri-dns
1362
	set ipcp enable req-sec-dns
1363

    
1364
EOD;
1365
	if (!isset($ppp['verbose_log']))
1366
		$mpdconf .= <<<EOD
1367
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1368

    
1369
EOD;
1370
	foreach($ports as $pid => $port){
1371
		$port = get_real_interface($port);
1372
		$mpdconf .= <<<EOD
1373

    
1374
	create link static {$interface}_link{$pid} {$type}
1375
	set link action bundle {$interface}
1376
	set link {$multilink} multilink
1377
	set link keep-alive 10 60
1378
	set link max-redial 0
1379

    
1380
EOD;
1381
		if (isset($ppp['shortseq']))
1382
			$mpdconf .= <<<EOD
1383
	set link no shortseq
1384

    
1385
EOD;
1386

    
1387
		if (isset($ppp['acfcomp']))
1388
			$mpdconf .= <<<EOD
1389
	set link no acfcomp
1390

    
1391
EOD;
1392

    
1393
		if (isset($ppp['protocomp']))
1394
			$mpdconf .= <<<EOD
1395
	set link no protocomp
1396

    
1397
EOD;
1398

    
1399
		$mpdconf .= <<<EOD
1400
	set link disable chap pap
1401
	set link accept chap pap eap
1402
	set link disable incoming
1403

    
1404
EOD;
1405

    
1406

    
1407
		if (!empty($bandwidths[$pid]))
1408
			$mpdconf .= <<<EOD
1409
	set link bandwidth {$bandwidths[$pid]}
1410

    
1411
EOD;
1412

    
1413
		if (empty($mtus[$pid]))
1414
			$mtus[$pid] = "1492";
1415
			$mpdconf .= <<<EOD
1416
	set link mtu {$mtus[$pid]}
1417

    
1418
EOD;
1419

    
1420
		if (!empty($mrus[$pid]))
1421
			$mpdconf .= <<<EOD
1422
	set link mru {$mrus[$pid]}
1423

    
1424
EOD;
1425

    
1426
		if (!empty($mrrus[$pid]))
1427
			$mpdconf .= <<<EOD
1428
	set link mrru {$mrrus[$pid]}
1429

    
1430
EOD;
1431

    
1432
		$mpdconf .= <<<EOD
1433
	set auth authname "{$ppp['username']}"
1434
	set auth password {$passwd}
1435

    
1436
EOD;
1437
		if ($type == "modem") {
1438
			$mpdconf .= <<<EOD
1439
	set modem device {$ppp['ports']}
1440
	set modem script DialPeer
1441
	set modem idle-script Ringback
1442
	set modem watch -cd
1443
	set modem var \$DialPrefix "DT"
1444
	set modem var \$Telephone "{$ppp['phone']}"
1445

    
1446
EOD;
1447
		}
1448
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1449
			$mpdconf .= <<<EOD
1450
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1451

    
1452
EOD;
1453
		}
1454
		if (isset($ppp['initstr']) && $type == "modem") {
1455
			$initstr = base64_decode($ppp['initstr']);
1456
			$mpdconf .= <<<EOD
1457
	set modem var \$InitString "{$initstr}"
1458

    
1459
EOD;
1460
		}
1461
		if (isset($ppp['simpin']) && $type == "modem") {
1462
			$mpdconf .= <<<EOD
1463
	set modem var \$SimPin "{$ppp['simpin']}"
1464
	set modem var \$PinWait "{$ppp['pin-wait']}"
1465

    
1466
EOD;
1467
		}
1468
		if (isset($ppp['apn']) && $type == "modem") {
1469
			$mpdconf .= <<<EOD
1470
	set modem var \$APN "{$ppp['apn']}"
1471
	set modem var \$APNum "{$ppp['apnum']}"
1472

    
1473
EOD;
1474
		}
1475
		if (isset($ppp['provider']) && $type == "pppoe") {
1476
			$mpdconf .= <<<EOD
1477
	set pppoe service "{$ppp['provider']}"
1478

    
1479
EOD;
1480
		}
1481
		if ($type == "pppoe")
1482
			$mpdconf .= <<<EOD
1483
	set pppoe iface {$port}
1484

    
1485
EOD;
1486

    
1487
		if ($type == "pptp" || $type == "l2tp") {
1488
			$mpdconf .= <<<EOD
1489
	set {$type} self {$localips[$pid]}
1490
	set {$type} peer {$gateways[$pid]}
1491
	set {$type} disable windowing
1492

    
1493
EOD;
1494
		}
1495
		
1496
		$mpdconf .= "\topen\r\n";
1497
	} //end foreach($port)
1498

    
1499

    
1500
	/* Generate mpd.conf. If mpd_[interface].conf exists in the conf path, then link to it instead of generating a fresh conf file. */
1501
	if (file_exists("{$g['conf_path']}/mpd_{$interface}.conf"))
1502
		mwexec("/bin/ln -s {$g['conf_path']}/mpd_{$interface}.conf {$g['varetc_path']}/.");
1503
	else {
1504
		$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1505
		if (!$fd) {
1506
			log_error("Error: cannot open mpd_{$interface}.conf in interface_ppps_configure().\n");
1507
			return 0;
1508
		}
1509
		// Write out mpd_ppp.conf
1510
		fwrite($fd, $mpdconf);
1511
		fclose($fd);
1512
	}
1513

    
1514
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1515
	if (isset($ppp['uptime'])) {
1516
		if (!file_exists("/conf/{$pppif}.log")) {
1517
			conf_mount_rw();
1518
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1519
			conf_mount_ro();
1520
		}
1521
	} else {
1522
		if (file_exists("/conf/{$pppif}.log")) {
1523
			conf_mount_rw();
1524
			mwexec("rm -f /conf/{$pppif}.log");
1525
			conf_mount_ro();
1526
		}
1527
	}
1528

    
1529
	/* fire up mpd */
1530
	mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/{$ppp['type']}_{$interface}.pid -s ppp {$ppp['type']}client");
1531

    
1532
	// Check for PPPoE periodic reset request 
1533
	if ($type == "pppoe") {
1534
		if (isset($ppp['pppoe-reset-type']))
1535
			setup_pppoe_reset_file($ppp['if'], $interface);
1536
		else
1537
			setup_pppoe_reset_file($ppp['if']);
1538
	}
1539

    
1540
	return 1;
1541
}
1542

    
1543
function interfaces_carp_setup() {
1544
	global $g, $config;
1545

    
1546
	$balanacing = "";
1547
	$pfsyncinterface = "";
1548
	$pfsyncenabled = "";
1549
	if(isset($config['system']['developerspew'])) {
1550
		$mt = microtime();
1551
		echo "interfaces_carp_setup() being called $mt\n";
1552
	}
1553

    
1554
	// Prepare CmdCHAIN that will be used to execute commands.
1555
	$cmdchain = new CmdCHAIN();	
1556

    
1557
	if ($g['booting']) {
1558
		echo "Configuring CARP settings...";
1559
		mute_kernel_msgs();
1560
	}
1561

    
1562
	/* suck in configuration items */
1563
	if($config['installedpackages']['carpsettings']) {
1564
		if($config['installedpackages']['carpsettings']['config']) {
1565
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1566
				$pfsyncenabled = $carp['pfsyncenabled'];
1567
				$balanacing = $carp['balancing'];
1568
				$pfsyncinterface = $carp['pfsyncinterface'];
1569
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1570
			}
1571
		}
1572
	} else {
1573
		unset($pfsyncinterface);
1574
		unset($balanacing);
1575
		unset($pfsyncenabled);
1576
	}
1577

    
1578
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1579
	if($balanacing) {
1580
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1581
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1582
	} else
1583
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1584

    
1585
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=1", true);
1586
	if (!empty($pfsyncinterface))
1587
		$carp_sync_int = get_real_interface($pfsyncinterface);
1588

    
1589
	if($g['booting']) {
1590
		/*    install rules to alllow pfsync to sync up during boot
1591
		 *    carp interfaces will remain down until the bootup sequence finishes
1592
		 */
1593
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1594
		if ($fd) {
1595
			fwrite($fd, "pass quick proto carp all keep state\n");
1596
			fwrite($fd, "pass quick proto pfsync all\n");
1597
			fwrite($fd, "pass out quick from any to any keep state\n");
1598
			fclose($fd);
1599
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1600
		} else
1601
			log_error("Could not create rules.boot file!");
1602
	}
1603

    
1604
	/* setup pfsync interface */
1605
	if($carp_sync_int and $pfsyncenabled) {
1606
		if (is_ipaddr($pfsyncpeerip))
1607
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1608
		else
1609
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1610
	} else
1611
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1612

    
1613
	if($config['virtualip']['vip'])
1614
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1615
	else
1616
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1617
	
1618
	if($g['debug'])
1619
		$cmdchain->setdebug(); // optional for verbose logging
1620

    
1621
	$cmdchain->execute();
1622
	$cmdchain->clear();
1623

    
1624
	if ($g['booting']) {
1625
		unmute_kernel_msgs();
1626
		echo "done.\n";
1627
	}
1628
}
1629

    
1630
function interface_proxyarp_configure($interface = "") {
1631
	global $config, $g;
1632
	if(isset($config['system']['developerspew'])) {
1633
		$mt = microtime();
1634
		echo "interface_proxyarp_configure() being called $mt\n";
1635
	}
1636

    
1637
	/* kill any running choparp */
1638
	if (empty($interface))
1639
		killbyname("choparp");
1640
	else {
1641
		$vipif = get_real_interface($interface);
1642
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1643
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1644
	}
1645

    
1646
	$paa = array();
1647
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1648

    
1649
		/* group by interface */
1650
		foreach ($config['virtualip']['vip'] as $vipent) {
1651
			if ($vipent['mode'] === "proxyarp") {
1652
				if ($vipent['interface'])
1653
					$proxyif = $vipent['interface'];
1654
				else
1655
					$proxyif = "wan";
1656
				
1657
				if (!empty($interface) && $interface != $proxyif)
1658
					continue;
1659

    
1660
				if (!is_array($paa[$proxyif]))
1661
					$paa[$proxyif] = array();
1662

    
1663
				$paa[$proxyif][] = $vipent;
1664
			}
1665
		}
1666
	}
1667

    
1668
	if (!empty($interface)) {
1669
		if (is_array($paa[$interface])) {
1670
			$paaifip = get_interface_ip($interface);
1671
                        if (!is_ipaddr($paaifip))
1672
                                return;
1673
                        $args = get_real_interface($interface) . " auto";
1674
                        foreach ($paa[$interface] as $paent) {
1675
                                if (isset($paent['subnet']))
1676
                                        $args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1677
                                else if (isset($paent['range']))
1678
                                        $args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1679
                        }
1680
                        mwexec_bg("/usr/local/sbin/choparp " . $args);	
1681
		}
1682
	} else if (count($paa) > 0) {
1683
		foreach ($paa as $paif => $paents)  {
1684
			$paaifip = get_interface_ip($paif);
1685
			if (!is_ipaddr($paaifip))
1686
				continue;
1687
			$args = get_real_interface($paif) . " auto";
1688
			foreach ($paents as $paent) {
1689
				if (isset($paent['subnet']))
1690
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1691
				else if (isset($paent['range']))
1692
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1693
			}
1694
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1695
		}
1696
	}
1697
}
1698

    
1699
function interfaces_vips_configure($interface = "") {
1700
	global $g, $config;
1701
	if(isset($config['system']['developerspew'])) {
1702
		$mt = microtime();
1703
		echo "interfaces_vips_configure() being called $mt\n";
1704
	}
1705
	$paa = array();
1706
	if(is_array($config['virtualip']['vip'])) {
1707
		$carp_setuped = false;
1708
		$anyproxyarp = false;
1709
		foreach ($config['virtualip']['vip'] as $vip) {
1710
			switch ($vip['mode']) {
1711
			case "proxyarp":
1712
				/* nothing it is handled on interface_proxyarp_configure() */
1713
				if ($interface <> "" && $vip['interface'] <> $interface)
1714
					continue;
1715
				$anyproxyarp = true;
1716
				break;
1717
			case "ipalias":
1718
				if ($interface <> "" && $vip['interface'] <> $interface)
1719
					continue;
1720
				interface_ipalias_configure(&$vip);
1721
				break;
1722
			case "carp":
1723
				if ($interface <> "" && $vip['interface'] <> $interface)
1724
					continue;
1725
				if ($carp_setuped == false) {
1726
					interfaces_carp_setup();
1727
					$carp_setuped = true;
1728
				}
1729
				interface_carp_configure($vip);
1730
				break;
1731
			case "carpdev-dhcp":
1732
				if ($interface <> "" && $vip['interface'] <> $interface)
1733
					continue;
1734
				interface_carpdev_configure($vip);
1735
				break;
1736
			}
1737
		}
1738
		
1739
		if ($anyproxyarp == true)
1740
			interface_proxyarp_configure();
1741
	}
1742
}
1743

    
1744
function interface_ipalias_configure(&$vip) {
1745

    
1746
	if ($vip['mode'] == "ipalias") {
1747
		$if = get_real_interface($vip['interface']);
1748
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1749
	}
1750
}
1751

    
1752
function interface_reload_carps($cif) {
1753
	global $config;
1754

    
1755
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1756
	if (empty($carpifs))
1757
		return;
1758

    
1759
	$carps = explode(" ", $carpifs);
1760
	if(is_array($config['virtualip']['vip'])) {
1761
		$viparr = &$config['virtualip']['vip'];
1762
		foreach ($viparr as $vip) {
1763
			if (in_array($vip['carpif'], $carps)) {
1764
				switch ($vip['mode']) {
1765
				case "carp":
1766
					interface_vip_bring_down($vip);
1767
					sleep(1);
1768
					interface_carp_configure($vip);
1769
					break;
1770
				case "carpdev-dhcp":
1771
					interface_vip_bring_down($vip);
1772
					sleep(1);
1773
					interface_carpdev_configure($vip);
1774
					break;
1775
				case "ipalias":
1776
					interface_vip_bring_down($vip);
1777
					sleep(1);
1778
					interface_ipalias_configure($vip);
1779
					break;
1780
				}
1781
			}
1782
		}
1783
	}
1784
}
1785

    
1786
function interface_carp_configure(&$vip) {
1787
	global $config, $g;
1788
	if(isset($config['system']['developerspew'])) {
1789
		$mt = microtime();
1790
		echo "interface_carp_configure() being called $mt\n";
1791
	}
1792

    
1793
	if ($vip['mode'] != "carp")
1794
		return;
1795

    
1796
	$vip_password = $vip['password'];
1797
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1798
	if ($vip['password'] != "")
1799
		$password = " pass {$vip_password}";
1800

    
1801
	// set the vip interface to the vhid
1802
	$vipif = "vip{$vip['vhid']}";
1803

    
1804
	/*
1805
	 * ensure the interface containing the VIP really exists
1806
 	 * prevents a panic if the interface is missing or invalid
1807
	 */
1808
	$realif = get_real_interface($vip['interface']);
1809
	if (!does_interface_exist($realif)) {
1810
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1811
		return;
1812
	}
1813

    
1814
	/* Ensure CARP IP really exists prior to loading up. */
1815
	$ww_subnet_ip = find_interface_ip($realif);
1816
	$ww_subnet_bits = find_interface_subnet($realif);
1817
	if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
1818
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1819
		return;
1820
	}
1821

    
1822
	/* create the carp interface and setup */
1823
	if (does_interface_exist($vipif)) {
1824
		pfSense_interface_flags($vipif, -IFF_UP);
1825
	} else {
1826
		$carpif = pfSense_interface_create("carp");
1827
		pfSense_interface_rename($carpif, $vipif);
1828
		pfSense_ngctl_name("{$carpif}:", $vipif);
1829
	}
1830

    
1831
	/* invalidate interface cache */
1832
	get_interface_arr(true);
1833

    
1834
	$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
1835
	$advbase = "";
1836
	if (!empty($vip['advbase']))
1837
		$advbase = "advbase {$vip['advbase']}";
1838
	mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
1839

    
1840
	interfaces_bring_up($vipif);
1841
	
1842
	return $vipif;
1843
}
1844

    
1845
function interface_carpdev_configure(&$vip) {
1846
	global $g;
1847

    
1848
	if ($vip['mode'] != "carpdev-dhcp")
1849
		return;
1850

    
1851
	$vip_password = $vip['password'];
1852
	$vip_password = str_replace(" ", "", $vip_password);
1853
	if($vip['password'] != "")
1854
		$password = " pass \"" . $vip_password . "\"";
1855

    
1856
	if (empty($vip['interface']))
1857
		return;
1858

    
1859
	$vipif = "vip" . $vip['vhid'];
1860
	$realif = get_real_interface($vip['interface']);
1861
	interfaces_bring_up($realif);
1862
	/*
1863
	 * ensure the interface containing the VIP really exists
1864
	 * prevents a panic if the interface is missing or invalid
1865
	 */
1866
	if (!does_interface_exist($realif)) {
1867
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1868
		return;
1869
	}
1870

    
1871
	if (does_interface_exist($vipif)) {
1872
		interface_bring_down($vipif);
1873
	} else {
1874
		$carpdevif = exec("/sbin/ifconfig carp create");
1875
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1876
		pfSense_ngctl_name("{$carpdevif}:", $vipif);
1877
	}
1878

    
1879
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} advbase {$vip['advbase']} {$password}");
1880
	interfaces_bring_up($vipif);
1881

    
1882
	/*
1883
	 * XXX: BIG HACK but carpdev needs ip services active
1884
	 *      before even starting something as dhclient.
1885
	 *      I do not know if this is a feature or a bug
1886
	 *      but better than track it make it work ;) .
1887
	 */
1888
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1889
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1890

    
1891
	/* generate dhclient_wan.conf */
1892
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1893
	if ($fd) {
1894
		$dhclientconf = "";
1895

    
1896
		$dhclientconf .= <<<EOD
1897
interface "{$vipif}" {
1898
timeout 60;
1899
retry 1;
1900
select-timeout 0;
1901
initial-interval 1;
1902
script "/sbin/dhclient-script";
1903
}
1904

    
1905
EOD;
1906

    
1907
		fwrite($fd, $dhclientconf);
1908
		fclose($fd);
1909

    
1910
		/* fire up dhclient */
1911
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} >{$g['tmp_path']}/{$vipif}_output 2>{$g['tmp_path']}/{$vipif}_error_output", false);
1912
	} else {
1913
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1914
		mwexec("/sbin/dhclient -b {$vipif}");
1915
	}
1916

    
1917
	return $vipif;
1918
}
1919

    
1920
function interface_wireless_clone($realif, $wlcfg) {
1921
	global $config, $g;
1922
	/*   Check to see if interface has been cloned as of yet.  
1923
	 *   If it has not been cloned then go ahead and clone it.
1924
	 */
1925
	$needs_clone = false;
1926
	if(is_array($wlcfg['wireless']))
1927
		$wlcfg_mode = $wlcfg['wireless']['mode'];
1928
	else
1929
		$wlcfg_mode = $wlcfg['mode'];
1930
	switch($wlcfg_mode) {
1931
		 case "hostap":
1932
			$mode = "wlanmode hostap";
1933
			break;
1934
		 case "adhoc":
1935
			$mode = "wlanmode adhoc";
1936
			break;
1937
		 default:
1938
			$mode = "";
1939
			break;
1940
	}
1941
	$baseif = interface_get_wireless_base($wlcfg['if']);
1942
	if(does_interface_exist($realif)) {
1943
		exec("/sbin/ifconfig {$realif}", $output, $ret);
1944
		$ifconfig_str = implode($output);
1945
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
1946
			log_error("Interface {$realif} changed to hostap mode");
1947
			$needs_clone = true;
1948
		}
1949
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
1950
			log_error("Interface {$realif} changed to adhoc mode");
1951
			$needs_clone = true;
1952
		}
1953
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
1954
			log_error("Interface {$realif} changed to infrastructure mode");
1955
			$needs_clone = true;
1956
		}
1957
	} else {
1958
		$needs_clone = true;
1959
	}
1960

    
1961
	if($needs_clone == true) {
1962
		/* remove previous instance if it exists */
1963
		if(does_interface_exist($realif))
1964
			pfSense_interface_destroy($realif);
1965

    
1966
		log_error("Cloning new wireless interface {$realif}");
1967
		// Create the new wlan interface. FreeBSD returns the new interface name.
1968
		// example:  wlan2
1969
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1970
		if($ret <> 0) {
1971
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1972
			return false;
1973
		}
1974
		$newif = trim($out[0]);
1975
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1976
		pfSense_interface_rename($newif, $realif);
1977
		// FIXME: not sure what ngctl is for. Doesn't work.
1978
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1979
		file_put_contents("{$g['tmp_path']}/{$realif}_oldmac", get_interface_mac($realif));
1980
	}
1981
	return true;
1982
}
1983

    
1984
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1985
	global $config, $g;
1986

    
1987
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
1988
	                         'diversity', 'txantenna', 'rxantenna', 'distance',
1989
	                         'regdomain', 'regcountry', 'reglocation');
1990

    
1991
	if(!is_interface_wireless($ifcfg['if']))
1992
		return;
1993

    
1994
	$baseif = interface_get_wireless_base($ifcfg['if']);
1995

    
1996
	// Sync shared settings for assigned clones
1997
	$iflist = get_configured_interface_list(false, true);
1998
	foreach ($iflist as $if) {
1999
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
2000
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
2001
				foreach ($shared_settings as $setting) {
2002
					if ($sync_changes) {
2003
						if (isset($ifcfg['wireless'][$setting]))
2004
							$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
2005
						else if (isset($config['interfaces'][$if]['wireless'][$setting]))
2006
							unset($config['interfaces'][$if]['wireless'][$setting]);
2007
					} else {
2008
						if (isset($config['interfaces'][$if]['wireless'][$setting]))
2009
							$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
2010
						else if (isset($ifcfg['wireless'][$setting]))
2011
							unset($ifcfg['wireless'][$setting]);
2012
					}
2013
				}
2014
				if (!$sync_changes)
2015
					break;
2016
			}
2017
		}
2018
	}
2019

    
2020
	// Read or write settings at shared area
2021
	if (isset($config['wireless']['interfaces'][$baseif])) {
2022
		foreach ($shared_settings as $setting) {
2023
			if ($sync_changes) {
2024
				if (isset($ifcfg['wireless'][$setting]))
2025
					$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
2026
				else if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2027
					unset($config['wireless']['interfaces'][$baseif][$setting]);
2028
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2029
				if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2030
					$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
2031
				else if (isset($ifcfg['wireless'][$setting]))
2032
					unset($ifcfg['wireless'][$setting]);
2033
			}
2034
		}
2035
	}
2036

    
2037
	// Sync the mode on the clone creation page with the configured mode on the interface
2038
	if (interface_is_wireless_clone($ifcfg['if'])) {
2039
		foreach ($config['wireless']['clone'] as &$clone) {
2040
			if ($clone['cloneif'] == $ifcfg['if']) {
2041
				if ($sync_changes) {
2042
					$clone['mode'] = $ifcfg['wireless']['mode'];
2043
				} else {
2044
					$ifcfg['wireless']['mode'] = $clone['mode'];
2045
				}
2046
				break;
2047
			}
2048
		}
2049
		unset($clone);
2050
	}
2051
}
2052

    
2053
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2054
	global $config, $g;
2055

    
2056
	/*    open up a shell script that will be used to output the commands.
2057
	 *    since wireless is changing a lot, these series of commands are fragile
2058
     *    and will sometimes need to be verified by a operator by executing the command
2059
     *    and returning the output of the command to the developers for inspection.  please
2060
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
2061
	 */
2062

    
2063
	// Remove script file
2064
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2065

    
2066
	// Clone wireless nic if needed.
2067
	interface_wireless_clone($if, $wl);
2068

    
2069
	// Reject inadvertent changes to shared settings in case the interface hasn't been configured.
2070
	interface_sync_wireless_clones($wl, false);
2071

    
2072
	$fd_set = fopen("{$g['tmp_path']}/{$if}_setup.sh","w");
2073
	fwrite($fd_set, "#!/bin/sh\n");
2074
	fwrite($fd_set, "# {$g['product_name']} wireless configuration script.\n\n");
2075

    
2076
	/* set values for /path/program */
2077
	$hostapd = "/usr/sbin/hostapd";
2078
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2079
	$ifconfig = "/sbin/ifconfig";
2080
	$sysctl = "/sbin/sysctl";
2081
	$killall = "/usr/bin/killall";
2082

    
2083
	/* Set all wireless ifconfig variables (splitt up to get rid of needed checking) */
2084

    
2085
	$wlcmd = array();
2086
	$wl_sysctl = array();
2087
	/* Make sure it's up */
2088
	$wlcmd[] = "up";
2089
	/* Set a/b/g standard */
2090
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
2091
	$wlcmd[] = "mode " . escapeshellarg($standard);
2092

    
2093
	/* XXX: Disable ampdu for now on mwl when running in 11n mode
2094
	 * to prevent massive packet loss under certain conditions. */
2095
	if(preg_match("/^mwl/i", $if) && ($standard == "11ng" || $standard == "11na"))
2096
		$wlcmd[] = "-ampdu";
2097

    
2098
	/* Set ssid */
2099
	if($wlcfg['ssid'])
2100
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2101

    
2102
	/* Set 802.11g protection mode */
2103
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2104

    
2105
	/* set wireless channel value */
2106
	if(isset($wlcfg['channel'])) {
2107
		if($wlcfg['channel'] == "0") {
2108
			$wlcmd[] = "channel any";
2109
		} else {
2110
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
2111
		}
2112
	}
2113

    
2114
	/* Set antenna diversity value */
2115
	if(isset($wlcfg['diversity']))
2116
		$wl_sysctl[] = "diversity=" . escapeshellarg($wlcfg['diversity']);
2117

    
2118
	/* Set txantenna value */
2119
	if(isset($wlcfg['txantenna']))
2120
		$wl_sysctl[] = "txantenna=" . escapeshellarg($wlcfg['txantenna']);
2121

    
2122
	/* Set rxantenna value */
2123
	if(isset($wlcfg['rxantenna']))
2124
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2125

    
2126
	/* set Distance value */
2127
	if($wlcfg['distance'])
2128
		$distance = escapeshellarg($wlcfg['distance']);
2129

    
2130
	/* Set wireless hostap mode */
2131
	if ($wlcfg['mode'] == "hostap") {
2132
		$wlcmd[] = "mediaopt hostap";
2133
	} else {
2134
		$wlcmd[] = "-mediaopt hostap";
2135
	}
2136

    
2137
	/* Set wireless adhoc mode */
2138
	if ($wlcfg['mode'] == "adhoc") {
2139
		$wlcmd[] = "mediaopt adhoc";
2140
	} else {
2141
		$wlcmd[] = "-mediaopt adhoc";
2142
	}
2143

    
2144
	/* Not neccesary to set BSS mode as this is default if adhoc and/or hostap is NOT set */
2145

    
2146
	/* handle hide ssid option */
2147
	if(isset($wlcfg['hidessid']['enable'])) {
2148
		$wlcmd[] = "hidessid";
2149
	} else {
2150
		$wlcmd[] = "-hidessid";
2151
	}
2152

    
2153
	/* handle pureg (802.11g) only option */
2154
	if(isset($wlcfg['pureg']['enable'])) {
2155
		$wlcmd[] = "mode 11g pureg";
2156
	} else {
2157
		$wlcmd[] = "-pureg";
2158
	}
2159

    
2160
	/* handle puren (802.11n) only option */
2161
	if(isset($wlcfg['puren']['enable'])) {
2162
		$wlcmd[] = "puren";
2163
	} else {
2164
		$wlcmd[] = "-puren";
2165
	}
2166

    
2167
	/* enable apbridge option */
2168
	if(isset($wlcfg['apbridge']['enable'])) {
2169
		$wlcmd[] = "apbridge";
2170
	} else {
2171
		$wlcmd[] = "-apbridge";
2172
	}
2173

    
2174
	/* handle turbo option */
2175
	if(isset($wlcfg['turbo']['enable'])) {
2176
		$wlcmd[] = "mediaopt turbo";
2177
	} else {
2178
		$wlcmd[] = "-mediaopt turbo";
2179
	}
2180

    
2181
	/* handle txpower setting */
2182
	/* if($wlcfg['txpower'] <> "")
2183
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
2184
	*/
2185
	/* handle wme option */
2186
	if(isset($wlcfg['wme']['enable'])) {
2187
		$wlcmd[] = "wme";
2188
	} else {
2189
		$wlcmd[] = "-wme";
2190
	}
2191

    
2192
	/* set up wep if enabled */
2193
	$wepset = "";
2194
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2195
		switch($wlcfg['wpa']['auth_algs']) {
2196
			case "1":
2197
				$wepset .= "authmode open wepmode on ";
2198
				break;
2199
			case "2":
2200
				$wepset .= "authmode shared wepmode on ";
2201
				break;
2202
			case "3":
2203
				$wepset .= "authmode mixed wepmode on ";
2204
		}
2205
		$i = 1;
2206
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2207
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2208
			if (isset($wepkey['txkey'])) {
2209
				$wlcmd[] = "weptxkey {$i} ";
2210
			}
2211
			$i++;
2212
		}
2213
		$wlcmd[] = $wepset;
2214
	} else {
2215
		$wlcmd[] = "authmode open wepmode off ";
2216
	}
2217

    
2218
	mwexec(kill_hostapd("{$if}"));
2219
	mwexec(kill_wpasupplicant("{$if}"));
2220

    
2221
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2222
	conf_mount_rw();
2223

    
2224
	switch ($wlcfg['mode']) {
2225
		case 'bss':
2226
			if (isset($wlcfg['wpa']['enable'])) {
2227
				$wpa .= <<<EOD
2228
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2229
ctrl_interface_group=0
2230
ap_scan=1
2231
#fast_reauth=1
2232
network={
2233
ssid="{$wlcfg['ssid']}"
2234
scan_ssid=1
2235
priority=5
2236
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2237
psk="{$wlcfg['wpa']['passphrase']}"
2238
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2239
group={$wlcfg['wpa']['wpa_pairwise']}
2240
}
2241
EOD;
2242

    
2243
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2244
				fwrite($fd, "{$wpa}");
2245
				fclose($fd);
2246
			}
2247
			break;
2248
		case 'hostap':
2249
			if($wlcfg['wpa']['passphrase']) 
2250
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2251
			else 
2252
				$wpa_passphrase = "";
2253
			if (isset($wlcfg['wpa']['enable'])) {
2254
				$wpa .= <<<EOD
2255
interface={$if}
2256
driver=bsd
2257
logger_syslog=-1
2258
logger_syslog_level=0
2259
logger_stdout=-1
2260
logger_stdout_level=0
2261
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2262
ctrl_interface={$g['varrun_path']}/hostapd
2263
ctrl_interface_group=wheel
2264
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2265
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2266
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2267
ssid={$wlcfg['ssid']}
2268
debug={$wlcfg['wpa']['debug_mode']}
2269
auth_algs={$wlcfg['wpa']['auth_algs']}
2270
wpa={$wlcfg['wpa']['wpa_mode']}
2271
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2272
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2273
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2274
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2275
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2276
{$wpa_passphrase}
2277

    
2278
EOD;
2279

    
2280
if (isset($wlcfg['wpa']['rsn_preauth'])) {
2281
	$wpa .= <<<EOD
2282
# Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2283
rsn_preauth=1
2284
rsn_preauth_interfaces={$if}
2285

    
2286
EOD;
2287

    
2288
}
2289
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2290
					$auth_server_port = "1812";
2291
					if($wlcfg['auth_server_port']) 
2292
						$auth_server_port = $wlcfg['auth_server_port'];
2293
					$wpa .= <<<EOD
2294

    
2295
ieee8021x=1
2296
auth_server_addr={$wlcfg['auth_server_addr']}
2297
auth_server_port={$auth_server_port}
2298
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2299

    
2300
EOD;
2301
				} else {
2302
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2303
				}
2304

    
2305
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2306
				fwrite($fd, "{$wpa}");
2307
				fclose($fd);
2308

    
2309
			}
2310
			break;
2311
	}
2312

    
2313
	/*
2314
	 *    all variables are set, lets start up everything
2315
	 */
2316

    
2317
	$baseif = interface_get_wireless_base($if);
2318
	preg_match("/^(.*?)([0-9]*)$/", $baseif, $baseif_split);
2319
	$wl_sysctl_prefix = 'dev.' . $baseif_split[1] . '.' . $baseif_split[2];
2320

    
2321
	/* set sysctls for the wireless interface */
2322
	if (!empty($wl_sysctl)) {
2323
		fwrite($fd_set, "# sysctls for {$baseif}\n");
2324
		foreach ($wl_sysctl as $wl_sysctl_line) {
2325
			fwrite($fd_set, "{$sysctl} {$wl_sysctl_prefix}.{$wl_sysctl_line}\n");
2326
		}
2327
	}
2328

    
2329
	/* set ack timers according to users preference (if he/she has any) */
2330
	if($distance) {
2331
		fwrite($fd_set, "# Enable ATH distance settings\n");
2332
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2333
	}
2334

    
2335
	if (isset($wlcfg['wpa']['enable'])) {
2336
		if ($wlcfg['mode'] == "bss") {
2337
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2338
		}
2339
		if ($wlcfg['mode'] == "hostap") {
2340
			/* add line to script to restore old mac to make hostapd happy */
2341
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2342
				$if_oldmac = file_get_contents("{$g['tmp_path']}/{$if}_oldmac");
2343
				if (is_macaddr($if_oldmac))
2344
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2345
						" link " . escapeshellarg($if_oldmac) . "\n");
2346
			}
2347

    
2348
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
2349

    
2350
			/* add line to script to restore spoofed mac after running hostapd */
2351
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2352
				if ($wl['spoofmac'])
2353
					$if_curmac = $wl['spoofmac'];
2354
				else
2355
					$if_curmac = get_interface_mac($if);
2356
				if (is_macaddr($if_curmac))
2357
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2358
						" link " . escapeshellarg($if_curmac) . "\n");
2359
			}
2360
		}
2361
	}
2362

    
2363
	fclose($fd_set);
2364
	conf_mount_ro();
2365

    
2366
	/* Making sure regulatory settings have actually changed
2367
	 * before applying, because changing them requires bringing
2368
	 * down all wireless networks on the interface. */
2369
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2370
	$ifconfig_str = implode($output);
2371
	unset($output);
2372
	$reg_changing = false;
2373

    
2374
	/* special case for the debug country code */
2375
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2376
		$reg_changing = true;
2377
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2378
		$reg_changing = true;
2379
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2380
		$reg_changing = true;
2381
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2382
		$reg_changing = true;
2383
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2384
		$reg_changing = true;
2385

    
2386
	if ($reg_changing) {
2387
		/* set regulatory domain */
2388
		if($wlcfg['regdomain'])
2389
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2390

    
2391
		/* set country */
2392
		if($wlcfg['regcountry'])
2393
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2394

    
2395
		/* set location */
2396
		if($wlcfg['reglocation'])
2397
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2398

    
2399
		$wlregcmd_args = implode(" ", $wlregcmd);
2400

    
2401
		/* build a complete list of the wireless clones for this interface */
2402
		$clone_list = array();
2403
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2404
			$clone_list[] = interface_get_wireless_clone($baseif);
2405
		if (is_array($config['wireless']['clone'])) {
2406
			foreach ($config['wireless']['clone'] as $clone) {
2407
				if ($clone['if'] == $baseif)
2408
					$clone_list[] = $clone['cloneif'];
2409
			}
2410
		}
2411

    
2412
		/* find which clones are up and bring them down */
2413
		$clones_up = array();
2414
		foreach ($clone_list as $clone_if) {
2415
			$clone_status = pfSense_get_interface_addresses($clone_if);
2416
			if ($clone_status['status'] == 'up') {
2417
				$clones_up[] = $clone_if;
2418
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2419
			}
2420
		}
2421

    
2422
		/* apply the regulatory settings */
2423
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2424

    
2425
		/* bring the clones back up that were previously up */
2426
		foreach ($clones_up as $clone_if) {
2427
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2428

    
2429
			/*
2430
			 * Rerun the setup script for the interface if it isn't this interface, the interface
2431
			 * is in infrastructure mode, and WPA is enabled.
2432
			 * This can be removed if wpa_supplicant stops dying when you bring the interface down.
2433
			 */
2434
			if ($clone_if != $if) {
2435
				$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
2436
				if ( !empty($friendly_if)
2437
				    && $config['interfaces'][$friendly_if]['wireless']['mode'] == "bss"
2438
				    && isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable']) ) {
2439
					mwexec("/bin/sh {$g['tmp_path']}/{$clone_if}_setup.sh");
2440
				}
2441
			}
2442
		}
2443
	}
2444

    
2445
	/* The mode must be specified in a separate command before ifconfig
2446
	 * will allow the mode and channel at the same time in the next. */
2447
	mwexec("/sbin/ifconfig {$if} mode " . escapeshellarg($standard));
2448

    
2449
	/* configure wireless */
2450
	$wlcmd_args = implode(" ", $wlcmd);
2451
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2452

    
2453
	
2454
	sleep(1);
2455
	/* execute hostapd and wpa_supplicant if required in shell */
2456
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2457

    
2458
	return 0;
2459

    
2460
}
2461

    
2462
function kill_hostapd($interface) {
2463
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2464
}
2465

    
2466
function kill_wpasupplicant($interface) {
2467
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2468
}
2469

    
2470
function find_dhclient_process($interface) {
2471
	if ($interface)
2472
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
2473
	else
2474
		$pid = 0;
2475

    
2476
	return intval($pid);
2477
}
2478

    
2479
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2480
	global $config, $g;
2481
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2482

    
2483
	$wancfg = $config['interfaces'][$interface];
2484

    
2485
	$realif = get_real_interface($interface);
2486
	$realhwif_array = get_parent_interface($interface);
2487
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
2488
	$realhwif = $realhwif_array[0];
2489

    
2490
	if (!$g['booting']) {
2491
		/* remove all IPv4 addresses */
2492
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2493

    
2494
		switch ($wancfg['ipaddr']) {
2495
			case 'pppoe':
2496
			case 'l2tp':
2497
			case 'pptp':
2498
			case 'ppp':
2499
				break;
2500
			default:
2501
				interface_bring_down($interface);
2502
				break;
2503
		}
2504
	}
2505

    
2506
	/* wireless configuration? */
2507
	if (is_array($wancfg['wireless']))
2508
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2509

    
2510
	if ($wancfg['spoofmac']) {
2511
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2512
			" link " . escapeshellarg($wancfg['spoofmac']));
2513

    
2514
                /*
2515
                 * All vlans need to spoof their parent mac address, too.  see
2516
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2517
                 */
2518
                if (is_array($config['vlans']['vlan'])) {
2519
                        foreach ($config['vlans']['vlan'] as $vlan) {
2520
                                if ($vlan['if'] == $realhwif)
2521
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2522
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2523
                        }
2524
                }
2525
	}  else {
2526
		$mac = get_interface_mac($realhwif);
2527
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2528
			/*   this is not a valid mac address.  generate a
2529
			 *   temporary mac address so the machine can get online.
2530
			 */
2531
			echo "Generating new MAC address.";
2532
			$random_mac = generate_random_mac_address();
2533
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2534
				" link " . escapeshellarg($random_mac));
2535
			$wancfg['spoofmac'] = $random_mac;
2536
			write_config();
2537
			file_notice("MAC Address altered", "The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface {$realif} has been automatically replaced with {$random_mac}", "Interfaces");
2538
		}
2539
	}
2540

    
2541
	/* media */
2542
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2543
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
2544
		if ($wancfg['media'])
2545
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2546
		if ($wancfg['mediaopt'])
2547
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2548
		mwexec($cmd);
2549
	}
2550
	if (!empty($wancfg['mtu']))
2551
		pfSense_interface_mtu($realhwif, $wancfg['mtu']);
2552

    
2553
	$options = pfSense_get_interface_addresses($realhwif);
2554
	if (is_array($options) && isset($options['caps']['polling'])) {
2555
		if (isset($config['system']['polling']))
2556
			pfSense_interface_capabilities($realif, IFCAP_POLLING);
2557
		else
2558
			pfSense_interface_capabilities($realif, -IFCAP_POLLING);
2559
	}
2560

    
2561
	/* skip vlans for checksumming and polling */
2562
        if (!stristr($realhwif, "vlan") && is_array($options)) {
2563
		$flags = 0;
2564
		if(isset($config['system']['disablechecksumoffloading'])) {
2565
			if (isset($options['encaps']['txcsum']))
2566
				$flags |= IFCAP_TXCSUM;
2567
			if (isset($options['encaps']['rxcsum']))
2568
				$flags |= IFCAP_RXCSUM;
2569
        	} else {
2570
 			if (!isset($options['caps']['txcsum']))
2571
				$flags |= IFCAP_TXCSUM;
2572
			if (!isset($options['caps']['rxcsum']))
2573
				$flags |= IFCAP_RXCSUM;
2574
        	}
2575

    
2576
        	if(isset($config['system']['disablesegmentationoffloading'])) {
2577
                	if (isset($options['encaps']['tso4']))
2578
				$flags |= IFCAP_TSO;
2579
                	if (isset($options['encaps']['tso6']))
2580
				$flags |= IFCAP_TSO;
2581
        	} else {
2582
                	if (!isset($options['caps']['tso4']))
2583
				$flags |= IFCAP_TSO;
2584
                	if (!isset($options['caps']['tso6']))
2585
				$flags |= IFCAP_TSO;
2586
        	}
2587

    
2588
        	if(isset($config['system']['disablelargereceiveoffloading'])) {
2589
                	if (isset($options['encaps']['lro']))
2590
				$flags |= IFCAP_LRO;
2591
        	} else {
2592
                	if (!isset($options['caps']['lro']))
2593
				$flags |= IFCAP_LRO;
2594
        	}
2595

    
2596
        	/* if the NIC supports polling *AND* it is enabled in the GUI */
2597
        	if (!isset($config['system']['polling']) || !isset($options['caps']['polling'])) {
2598
			$flags |= IFCAP_POLLING;
2599
		}
2600
               	pfSense_interface_capabilities($realhwif, -$flags);
2601
	}
2602

    
2603
	/* invalidate interface/ip/sn cache */
2604
	get_interface_arr(true);
2605
	unset($interface_ip_arr_cache[$realif]);
2606
	unset($interface_sn_arr_cache[$realif]);
2607

    
2608
	switch ($wancfg['ipaddr']) {
2609
		case 'carpdev-dhcp':
2610
			interface_carpdev_dhcp_configure($interface);
2611
			break;
2612
		case 'dhcp':
2613
			interface_dhcp_configure($interface);
2614
			break;
2615
		case 'pppoe':
2616
		case 'l2tp':
2617
		case 'pptp':
2618
		case 'ppp':
2619
			interface_ppps_configure($interface);
2620
			break;
2621
		default:
2622
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
2623
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2624
			} else if (substr($realif, 0, 3) == "gre") {
2625
				if (is_array($config['gres']['gre'])) {
2626
					foreach ($config['gres']['gre'] as $gre)
2627
						if ($gre['greif'] == $realif)
2628
							interface_gre_configure($gre);
2629
				}
2630
			} else if (substr($realif, 0, 3) == "gif") {
2631
				 if (is_array($config['gifs']['gif'])) {
2632
					foreach ($config['gifs']['gif'] as $gif)
2633
						if($gif['gifif'] == $interface)
2634
							interface_gif_configure($gif);
2635
				}
2636
			} else if (substr($realif, 0, 4) == "ovpn") {
2637
				/* XXX: Should be done anything?! */
2638
			}
2639
			break;
2640
	}
2641

    
2642
	if(does_interface_exist($wancfg['if']))
2643
		interfaces_bring_up($wancfg['if']);
2644

    
2645
	interface_netgraph_needed($interface);
2646
 	
2647
	if (!$g['booting']) {
2648
		link_interface_to_vips($interface, "update");
2649

    
2650
		unset($gre);
2651
		$gre = link_interface_to_gre($interface);
2652
		if (!empty($gre))
2653
			array_walk($gre, 'interface_gre_configure');
2654

    
2655
		unset($gif);
2656
		$gif = link_interface_to_gif($interface);
2657
		if (!empty($gif))
2658
                       	array_walk($gif, 'interface_gif_configure');
2659

    
2660
		if ($linkupevent == false) {
2661
			unset($bridgetmp);
2662
			$bridgetmp = link_interface_to_bridge($interface);
2663
			if (!empty($bridgetmp))
2664
				interface_bridge_add_member($bridgetmp, $realif);
2665
		}
2666

    
2667
		$grouptmp = link_interface_to_group($interface);
2668
		if (!empty($grouptmp))
2669
			array_walk($grouptmp, 'interface_group_add_member');
2670

    
2671
		if ($interface == "lan")
2672
			/* make new hosts file */
2673
			system_hosts_generate();
2674

    
2675
		if ($reloadall == true) {
2676

    
2677
			/* reconfigure static routes (kernel may have deleted them) */
2678
			system_routing_configure($interface);
2679

    
2680
			/* reload ipsec tunnels */
2681
			vpn_ipsec_configure();
2682

    
2683
			/* restart dnsmasq */
2684
			services_dnsmasq_configure();
2685

    
2686
			/* update dyndns */
2687
			send_event("service reload dyndns {$interface}");
2688

    
2689
			/* reload captive portal */
2690
			captiveportal_init_rules();
2691
		}
2692
	}
2693

    
2694
	return 0;
2695
}
2696

    
2697
function interface_carpdev_dhcp_configure($interface = "wan") {
2698
	global $config, $g;
2699

    
2700
	$wancfg = $config['interfaces'][$interface];
2701
	$wanif = $wancfg['if'];
2702
	/* bring wan interface up before starting dhclient */
2703
	if($wanif)
2704
		interfaces_bring_up($wanif);
2705
	else 
2706
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2707

    
2708
	return 0;
2709
}
2710

    
2711
function interface_dhcp_configure($interface = "wan") {
2712
	global $config, $g;
2713

    
2714
	$wancfg = $config['interfaces'][$interface];
2715
	if (empty($wancfg))
2716
		$wancfg = array();
2717

    
2718
	/* generate dhclient_wan.conf */
2719
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2720
	if (!$fd) {
2721
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2722
		return 1;
2723
	}
2724

    
2725
	if ($wancfg['dhcphostname']) {
2726
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2727
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2728
	} else {
2729
		$dhclientconf_hostname = "";
2730
	}
2731

    
2732
	$wanif = get_real_interface($interface);
2733
	if (empty($wanif)) {
2734
		log_error("Invalid interface \"{$interface}\" in interface_dhcp_configure()");
2735
		return 0;
2736
	}
2737
 	$dhclientconf = "";
2738
	
2739
	$dhclientconf .= <<<EOD
2740
interface "{$wanif}" {
2741
timeout 60;
2742
retry 1;
2743
select-timeout 0;
2744
initial-interval 1;
2745
	{$dhclientconf_hostname}
2746
	script "/sbin/dhclient-script";
2747
}
2748

    
2749
EOD;
2750

    
2751
if(is_ipaddr($wancfg['alias-address'])) {
2752
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2753
	$dhclientconf .= <<<EOD
2754
alias {
2755
	interface  "{$wanif}";
2756
	fixed-address {$wancfg['alias-address']};
2757
	option subnet-mask {$subnetmask};
2758
}
2759

    
2760
EOD;
2761
}
2762
	fwrite($fd, $dhclientconf);
2763
	fclose($fd);
2764

    
2765
	/* bring wan interface up before starting dhclient */
2766
	if($wanif)
2767
		interfaces_bring_up($wanif);
2768
	else 
2769
		log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
2770

    
2771
	/* fire up dhclient */
2772
	mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} > {$g['tmp_path']}/{$wanif}_output > {$g['tmp_path']}/{$wanif}_error_output");
2773

    
2774
	return 0;
2775
}
2776

    
2777
function interfaces_group_setup() {
2778
	global $config;
2779

    
2780
	if (!is_array($config['ifgroups']['ifgroupentry']))
2781
		return;
2782

    
2783
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2784
		interface_group_setup($groupar);
2785

    
2786
	return;
2787
}
2788

    
2789
function interface_group_setup(&$groupname /* The parameter is an array */) {
2790
	global $config;
2791

    
2792
	if (!is_array($groupname))
2793
		return;
2794
	$members = explode(" ", $groupname['members']);
2795
	foreach($members as $ifs) {
2796
		$realif = get_real_interface($ifs);
2797
		if ($realif)
2798
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2799
	}
2800

    
2801
	return;
2802
}
2803

    
2804
function interface_group_add_member($interface, $groupname) {
2805
	$interface = get_real_interface($interface);
2806
	mwexec("/sbin/ifconfig {$interface} group {$groupname}", true);
2807
}
2808
 
2809
/* COMPAT Function */
2810
function convert_friendly_interface_to_real_interface_name($interface) {
2811
	return get_real_interface($interface);
2812
}
2813

    
2814
/* COMPAT Function */
2815
function get_real_wan_interface($interface = "wan") {
2816
	return get_real_interface($interface);
2817
}
2818

    
2819
/* COMPAT Function */
2820
function get_current_wan_address($interface = "wan") {
2821
	return get_interface_ip($interface);
2822
}
2823

    
2824
/*
2825
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2826
 */
2827
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2828
        global $config;
2829

    
2830
	if (stristr($interface, "vip")) {
2831
                $index = intval(substr($interface, 3));
2832
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2833
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2834
                                if ($index == $vip['vhid'])
2835
                                        return $vip['interface'];
2836
                        }
2837
                }
2838
        }
2839

    
2840
        /* XXX: For speed reasons reference directly the interface array */
2841
	$ifdescrs = &$config['interfaces'];
2842
        //$ifdescrs = get_configured_interface_list(false, true);
2843

    
2844
        foreach ($ifdescrs as $if => $ifname) {
2845
                if ($config['interfaces'][$if]['if'] == $interface)
2846
                        return $if;
2847

    
2848
                if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
2849
                        return $if;
2850

    
2851
                $int = get_parent_interface($if);
2852
                if ($int == $interface)
2853
                        return $ifname;
2854
        }
2855
        return NULL;
2856
}
2857

    
2858
/* attempt to resolve interface to friendly descr */
2859
function convert_friendly_interface_to_friendly_descr($interface) {
2860
        global $config;
2861

    
2862
        switch ($interface) {
2863
        case "l2tp":
2864
        	$ifdesc = "L2TP";
2865
                break;
2866
	case "pptp":
2867
		$ifdesc = "PPTP";
2868
		break;
2869
	case "pppoe":
2870
		$ifdesc = "PPPoE";
2871
		break;
2872
	case "openvpn":
2873
		$ifdesc = "OpenVPN";
2874
		break;
2875
	case "enc0":
2876
	case "ipsec":
2877
		$ifdesc = "IPsec";
2878
		break;
2879
        default:
2880
                if (isset($config['interfaces'][$interface])) {
2881
                        if (empty($config['interfaces'][$interface]['descr']))
2882
                                $ifdesc = strtoupper($interface);
2883
                        else
2884
                                $ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
2885
			break;
2886
		} else if (substr($interface, 0, 3) == "vip") {
2887
			if (is_array($config['virtualip']['vip'])) {
2888
				foreach ($config['virtualip']['vip'] as $counter => $vip) {
2889
					if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2890
						if ($interface == "vip{$vip['vhid']}")
2891
							return "{$vip['subnet']} - {$vip['descr']}";
2892
					}
2893
				}
2894
                        }
2895
                } else {
2896
			/* if list */
2897
			$ifdescrs = get_configured_interface_with_descr(false, true);
2898
			foreach ($ifdescrs as $if => $ifname) {
2899
					if ($if == $interface || $ifname == $interface)
2900
						return $ifname;
2901
			}
2902
		}
2903
                break;
2904
        }
2905

    
2906
        return $ifdesc;
2907
}
2908

    
2909
function convert_real_interface_to_friendly_descr($interface) {
2910
        global $config;
2911

    
2912
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2913

    
2914
        if ($ifdesc) {
2915
                $iflist = get_configured_interface_with_descr(false, true);
2916
                return $iflist[$ifdesc];
2917
        }
2918

    
2919
        return $interface;
2920
}
2921

    
2922
/*
2923
 *  get_parent_interface($interface):
2924
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
2925
 *				or virtual interface (i.e. vlan)
2926
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
2927
 *			-- returns $interface passed in if $interface parent is not found
2928
 *			-- returns empty array if an invalid interface is passed
2929
 *	(Only handles ppps and vlans now.)
2930
 */
2931
function get_parent_interface($interface) {
2932
	global $config;
2933

    
2934
	$parents = array();
2935
	//Check that we got a valid interface passed
2936
	$realif = get_real_interface($interface);
2937
	if ($realif == NULL)
2938
		return $parents;
2939

    
2940
	// If we got a real interface, find it's friendly assigned name
2941
	$interface = convert_real_interface_to_friendly_interface_name($interface);
2942
		
2943
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
2944
		$ifcfg = $config['interfaces'][$interface];
2945
		switch ($ifcfg['ipaddr']) {
2946
			case "ppp":
2947
			case "pppoe":
2948
			case "pptp":
2949
			case "l2tp":
2950
				if (empty($parents))
2951
					if (is_array($config['ppps']['ppp']))
2952
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
2953
							if ($ppp_if == $ppp['if']) {
2954
								$ports = explode(',', $ppp['ports']);
2955
								foreach ($ports as $pid => $parent_if) 
2956
									$parents[$pid] = get_real_interface($parent_if);
2957
								break;
2958
							}
2959
						}
2960
				break;
2961
			case "dhcp":
2962
			case "static":
2963
			default:
2964
				// Handle _vlans
2965
				if (strstr($realif,"_vlan"))
2966
					if (is_array($config['vlans']['vlan'])) 
2967
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan)
2968
							if ($ifcfg['if'] == $vlan['vlanif']){
2969
								$parents[0] = $vlan['if'];
2970
								break;
2971
							}
2972
				break;
2973
		}
2974
	}
2975
	
2976
	if (empty($parents))
2977
		$parents[0] = $realif;
2978
	
2979
	return $parents;
2980
}
2981

    
2982
function interface_is_wireless_clone($wlif) {
2983
	if(!stristr($wlif, "_wlan")) {
2984
		return false;
2985
	} else {
2986
		return true;
2987
	}
2988
}
2989

    
2990
function interface_get_wireless_base($wlif) {
2991
	if(!stristr($wlif, "_wlan")) {
2992
		return $wlif;
2993
	} else {
2994
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2995
	}
2996
}
2997

    
2998
function interface_get_wireless_clone($wlif) {
2999
	if(!stristr($wlif, "_wlan")) {
3000
		return $wlif . "_wlan0";
3001
	} else {
3002
		return $wlif;
3003
	}
3004
}
3005

    
3006
function get_real_interface($interface = "wan") {
3007
    global $config;
3008

    
3009
	$wanif = NULL;
3010

    
3011
	switch ($interface) {
3012
	case "l2tp":
3013
		$wanif = "l2tp";
3014
		break;
3015
	case "pptp":
3016
		$wanif = "pptp";
3017
		break;
3018
	case "pppoe":
3019
		$wanif = "pppoe";
3020
		break;
3021
	case "openvpn":
3022
		$wanif = "openvpn";
3023
		break;
3024
	case "ipsec":
3025
	case "enc0":
3026
		$wanif = "enc0";
3027
		break;
3028
	case "ppp":
3029
		$wanif = "ppp";
3030
		break;
3031
	default:
3032
		// If a real interface was alread passed simply
3033
		// pass the real interface back.  This encourages
3034
		// the usage of this function in more cases so that
3035
		// we can combine logic for more flexibility.
3036
		if(does_interface_exist($interface)) {
3037
			$wanif = $interface;
3038
			break;
3039
		}
3040
		if (empty($config['interfaces'][$interface]))
3041
			break;
3042

    
3043
		$cfg = &$config['interfaces'][$interface];
3044

    
3045
		// Wireless cloned NIC support (FreeBSD 8+)
3046
		// interface name format: $parentnic_wlanparentnic#
3047
		// example: ath0_wlan0
3048
		if (is_interface_wireless($cfg['if'])) {
3049
			$wanif = interface_get_wireless_clone($cfg['if']);
3050
			break;
3051
		}
3052
		/*
3053
		if (empty($cfg['if'])) {
3054
			$wancfg = $cfg['if'];
3055
			break;
3056
		}
3057
		*/
3058

    
3059
		switch ($cfg['ipaddr']) {
3060
			case "carpdev-dhcp":
3061
				$viparr = &$config['virtualip']['vip'];
3062
				if(is_array($viparr))
3063
				foreach ($viparr as $counter => $vip) {
3064
					if ($vip['mode'] == "carpdev-dhcp") {
3065
						if($vip['interface'] == $interface) {
3066
							$wanif = "carp{$counter}";
3067
							break;
3068
						}
3069
					}
3070
				}
3071
				break;
3072
			case "pppoe": 
3073
			case "pptp": 
3074
			case "l2tp": 
3075
			case "ppp":
3076
				$wanif = $cfg['if'];
3077
				break;
3078
			default:
3079
				$wanif = $cfg['if'];
3080
				break;
3081
		}
3082
		break;
3083
	}
3084

    
3085
    return $wanif;
3086
}
3087

    
3088
/* Guess the physical interface by providing a IP address */
3089
function guess_interface_from_ip($ipaddress) {
3090
	if(! is_ipaddr($ipaddress)) {
3091
		return false;
3092
	}
3093
	/* create a route table we can search */
3094
	exec("netstat -rnWf inet", $output, $ret);
3095
	foreach($output as $line) {
3096
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
3097
			$fields = preg_split("/[ ]+/", $line);
3098
			if(ip_in_subnet($ipaddress, $fields[0])) {
3099
				return $fields[6];
3100
			}
3101
		}
3102
	}
3103
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
3104
	if(empty($ret)) {
3105
        	return false;
3106
	}
3107
	return $ret;
3108
}
3109

    
3110
/*
3111
 * find_ip_interface($ip): return the interface where an ip is defined
3112
 */
3113
function find_ip_interface($ip)
3114
{
3115
        /* if list */
3116
        $ifdescrs = get_configured_interface_list();
3117

    
3118
        foreach ($ifdescrs as $ifdescr => $ifname) {
3119
		if ($ip == get_interface_ip($ifname)) {
3120
                	$int = get_real_interface($ifname);
3121
			return $int;
3122
		}
3123
        }
3124
        return false;
3125
}
3126

    
3127
/*
3128
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
3129
 */
3130
function find_number_of_created_carp_interfaces() {
3131
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
3132
}
3133

    
3134
function get_all_carp_interfaces() {
3135
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
3136
	$ints = explode(" ", $ints);
3137
	return $ints;
3138
}
3139

    
3140
/*
3141
 * find_carp_interface($ip): return the carp interface where an ip is defined
3142
 */
3143
function find_carp_interface($ip) {
3144
	global $config;
3145
	if (is_array($config['virtualip']['vip'])) {
3146
		foreach ($config['virtualip']['vip'] as $vip) {
3147
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3148
				$carp_ip = get_interface_ip($vip['interface']);
3149
				$if = `ifconfig | grep '$ip ' -B1 | head -n1 | cut -d: -f1`;
3150
				if ($if)
3151
					return $if;
3152
			}
3153
		}
3154
	}
3155
}
3156

    
3157
function link_carp_interface_to_parent($interface) {
3158
        global $config;
3159

    
3160
        if ($interface == "")
3161
                return;
3162

    
3163
        $carp_ip = get_interface_ip($interface);
3164
        if (!is_ipaddr($carp_ip))
3165
                return;
3166

    
3167
        /* if list */
3168
        $ifdescrs = get_configured_interface_list();
3169
        foreach ($ifdescrs as $ifdescr => $ifname) {
3170
                $interfaceip = get_interface_ip($ifname);
3171
                $subnet_bits = get_interface_subnet($ifname);
3172
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
3173
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
3174
                        return $ifname;
3175
        }
3176

    
3177
        return "";
3178
}
3179

    
3180
/****f* interfaces/link_ip_to_carp_interface
3181
 * NAME
3182
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
3183
 * INPUTS
3184
 *   $ip
3185
 * RESULT
3186
 *   $carp_ints
3187
 ******/
3188
function link_ip_to_carp_interface($ip) {
3189
        global $config;
3190

    
3191
        if (!is_ipaddr($ip))
3192
                return;
3193

    
3194
        $carp_ints = "";
3195
        if (is_array($config['virtualip']['vip'])) {
3196
		$first = 0;
3197
		$carp_int = array();
3198
                foreach ($config['virtualip']['vip'] as $vip) {
3199
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3200
                                $carp_ip = $vip['subnet'];
3201
                                $carp_sn = $vip['subnet_bits'];
3202
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
3203
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
3204
					$carp_int[] = "vip{$vip['vhid']}";
3205
                        }
3206
                }
3207
		if (!empty($carp_int))
3208
			$carp_ints = implode(" ", array_unique($carp_int));
3209
        }
3210

    
3211
        return $carp_ints;
3212
}
3213

    
3214
function link_interface_to_vlans($int, $action = "") {
3215
	global $config;
3216

    
3217
	if (empty($int))
3218
		return;
3219

    
3220
	if (is_array($config['vlans']['vlan'])) {
3221
                foreach ($config['vlans']['vlan'] as $vlan) {
3222
			if ($int == $vlan['if']) {
3223
				if ($action == "update") {
3224
					interfaces_bring_up($int);
3225
				} else if ($action == "")
3226
					return $vlan;
3227
			}
3228
		}
3229
	}
3230
}
3231

    
3232
function link_interface_to_vips($int, $action = "") {
3233
        global $config;
3234

    
3235
        if (is_array($config['virtualip']['vip'])) {
3236
		foreach ($config['virtualip']['vip'] as $vip) {
3237
			if ($int == $vip['interface']) {
3238
				if ($action == "update") {
3239
					interface_vip_bring_down($vip);
3240
					interfaces_vips_configure($int);
3241
				} else
3242
					return $vip;
3243
			}
3244
		}
3245
	}
3246
}
3247

    
3248
/****f* interfaces/link_interface_to_bridge
3249
 * NAME
3250
 *   link_interface_to_bridge - Finds out a bridge group for an interface
3251
 * INPUTS
3252
 *   $ip
3253
 * RESULT
3254
 *   bridge[0-99]
3255
 ******/
3256
function link_interface_to_bridge($int) {
3257
        global $config;
3258

    
3259
        if (is_array($config['bridges']['bridged'])) {
3260
                foreach ($config['bridges']['bridged'] as $bridge) {
3261
			if (in_array($int, explode(',', $bridge['members'])))
3262
                                return "{$bridge['bridgeif']}";
3263
		}
3264
	}
3265
}
3266

    
3267
function link_interface_to_group($int) {
3268
        global $config;
3269

    
3270
	$result = array();
3271

    
3272
        if (is_array($config['ifgroups']['ifgroupentry'])) {
3273
                foreach ($config['ifgroups']['ifgroupentry'] as $group) {
3274
			if (in_array($int, explode(" ", $group['members'])))
3275
				$result[$group['ifname']] = $int;
3276
		}
3277
	}
3278

    
3279
	return $result;
3280
}
3281

    
3282
function link_interface_to_gre($interface) {
3283
        global $config;
3284

    
3285
	$result = array();
3286

    
3287
        if (is_array($config['gres']['gre'])) {
3288
                foreach ($config['gres']['gre'] as $gre)
3289
                        if($gre['if'] == $interface)
3290
				$result[] = $gre;
3291
	}
3292

    
3293
	return $result;
3294
}
3295

    
3296
function link_interface_to_gif($interface) {
3297
        global $config;
3298

    
3299
	$result = array();
3300

    
3301
        if (is_array($config['gifs']['gif'])) {
3302
                foreach ($config['gifs']['gif'] as $gif)
3303
                        if($gif['if'] == $interface)
3304
                                $result[] = $gif;
3305
	}
3306

    
3307
	return $result;
3308
}
3309

    
3310
/*
3311
 * find_interface_ip($interface): return the interface ip (first found)
3312
 */
3313
function find_interface_ip($interface, $flush = false)
3314
{
3315
	global $interface_ip_arr_cache;
3316
	global $interface_sn_arr_cache;
3317

    
3318
	$interface = str_replace("\n", "", $interface);
3319
	
3320
	if (!does_interface_exist($interface))
3321
		return;
3322

    
3323
	/* Setup IP cache */
3324
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
3325
		$ifinfo = pfSense_get_interface_addresses($interface);
3326
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3327
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3328
	}
3329

    
3330
	return $interface_ip_arr_cache[$interface];
3331
}
3332

    
3333
function find_interface_subnet($interface, $flush = false)
3334
{
3335
	global $interface_sn_arr_cache;
3336
	global $interface_ip_arr_cache;
3337

    
3338
	$interface = str_replace("\n", "", $interface);
3339
	if (does_interface_exist($interface) == false)
3340
		return;
3341

    
3342
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
3343
		$ifinfo = pfSense_get_interface_addresses($interface);
3344
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3345
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3346
        }
3347

    
3348
	return $interface_sn_arr_cache[$interface];
3349
}
3350

    
3351
function ip_in_interface_alias_subnet($interface, $ipalias) {
3352
	global $config;
3353

    
3354
	if (empty($interface) || !is_ipaddr($ipalias))
3355
		return false;
3356
	if (is_array($config['virtualip']['vip'])) {
3357
                foreach ($config['virtualip']['vip'] as $vip) {
3358
                        switch ($vip['mode']) {
3359
                        case "ipalias":
3360
                                if ($vip['interface'] <> $interface)
3361
                                        break;
3362
				if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']))
3363
					return true;
3364
                                break;
3365
                        }
3366
                }
3367
	}
3368

    
3369
	return false;
3370
}
3371

    
3372
function get_interface_ip($interface = "wan")
3373
{
3374
	$realif = get_real_interface($interface);
3375
	if (!$realif) {
3376
		if (preg_match("/^carp/i", $interface))
3377
			$realif = $interface;
3378
		else if (preg_match("/^vip/i", $interface))
3379
			$realif = $interface;
3380
		else
3381
			return null;
3382
	}
3383

    
3384
	$curip = find_interface_ip($realif);
3385
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
3386
		return $curip;
3387
	else
3388
		return null;
3389
}
3390

    
3391
function get_interface_subnet($interface = "wan")
3392
{
3393
	$realif = get_real_interface($interface);
3394
	if (!$realif) {
3395
                if (preg_match("/^carp/i", $interface))
3396
                        $realif = $interface;
3397
                else if (preg_match("/^vip/i", $interface))
3398
                        $realif = $interface;
3399
                else
3400
                        return null;
3401
        }
3402

    
3403
	$cursn = find_interface_subnet($realif);
3404
	if (!empty($cursn))
3405
		return $cursn;
3406

    
3407
	return null;
3408
}
3409

    
3410
/* return outside interfaces with a gateway */
3411
function get_interfaces_with_gateway() {
3412
	global $config;
3413

    
3414
	$ints = array();
3415

    
3416
	/* loop interfaces, check config for outbound */
3417
	foreach($config['interfaces'] as $ifdescr => $ifname) {
3418
		switch ($ifname['ipaddr']) {
3419
			case "dhcp":
3420
			case "carpdev-dhcp":
3421
			case "ppp";
3422
			case "pppoe":
3423
			case "pptp":
3424
			case "l2tp":
3425
			case "ppp";
3426
				$ints[$ifdescr] = $ifdescr;
3427
			break;
3428
			default:
3429
				if (substr($ifname['if'], 0, 5) ==  "ovpnc" ||
3430
				    !empty($ifname['gateway']))
3431
					$ints[$ifdescr] = $ifdescr;
3432
			break;
3433
		}
3434
	}
3435
	return $ints;
3436
}
3437

    
3438
/* return true if interface has a gateway */
3439
function interface_has_gateway($friendly) {
3440
	global $config;
3441

    
3442
	if (!empty($config['interfaces'][$friendly])) {
3443
		$ifname = &$config['interfaces'][$friendly];
3444
		switch ($ifname['ipaddr']) {
3445
			case "dhcp":
3446
			case "carpdev-dhcp":
3447
			case "pppoe":
3448
			case "pptp":
3449
			case "l2tp":
3450
			case "ppp";
3451
				return true;
3452
			break;
3453
			default:
3454
				if (substr($ifname['if'], 0, 5) ==  "ovpnc")
3455
					return true;
3456
				if (!empty($ifname['gateway']))
3457
					return true;
3458
			break;
3459
		}
3460
	}
3461

    
3462
	return false;
3463
}
3464

    
3465
/****f* interfaces/is_altq_capable
3466
 * NAME
3467
 *   is_altq_capable - Test if interface is capable of using ALTQ
3468
 * INPUTS
3469
 *   $int            - string containing interface name
3470
 * RESULT
3471
 *   boolean         - true or false
3472
 ******/
3473

    
3474
function is_altq_capable($int) {
3475
        /* Per:
3476
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3477
         * Only the following drivers have ALTQ support
3478
         */
3479
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3480
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3481
			"hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
3482
			"npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk",
3483
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3484
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
3485
			"l2tp", "ppp");
3486

    
3487
        $int_family = preg_split("/[0-9]+/", $int);
3488

    
3489
        if (in_array($int_family[0], $capable))
3490
                return true;
3491
	else if (stristr($int, "vlan")) /* VLANs are name $parent_$vlan now */
3492
		return true;
3493
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
3494
		return true;
3495
        else
3496
                return false;
3497
}
3498

    
3499
/****f* interfaces/is_interface_wireless
3500
 * NAME
3501
 *   is_interface_wireless - Returns if an interface is wireless
3502
 * RESULT
3503
 *   $tmp       - Returns if an interface is wireless
3504
 ******/
3505
function is_interface_wireless($interface) {
3506
        global $config, $g;
3507

    
3508
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3509
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3510
                if (preg_match($g['wireless_regex'], $interface)) {
3511
                        if (isset($config['interfaces'][$friendly]))
3512
                                $config['interfaces'][$friendly]['wireless'] = array();
3513
                        return true;
3514
                }
3515
                return false;
3516
        } else
3517
                return true;
3518
}
3519

    
3520
function get_wireless_modes($interface) {
3521
	/* return wireless modes and channels */
3522
	$wireless_modes = array();
3523

    
3524
	$wlif = get_real_interface($interface);
3525

    
3526
	if($wlif != NULL && is_interface_wireless($wlif)) {
3527
		$cloned_interface = get_real_interface($interface);
3528
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3529
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3530
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3531

    
3532
		$interface_channels = "";
3533
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3534
		$interface_channel_count = count($interface_channels);
3535

    
3536
		$c = 0;
3537
		while ($c < $interface_channel_count)
3538
		{
3539
			$channel_line = explode(",", $interface_channels["$c"]);
3540
			$wireless_mode = trim($channel_line[0]);
3541
			$wireless_channel = trim($channel_line[1]);
3542
			if(trim($wireless_mode) != "") {
3543
				/* if we only have 11g also set 11b channels */
3544
				if($wireless_mode == "11g") {
3545
					if(!isset($wireless_modes["11b"]))
3546
						$wireless_modes["11b"] = array();
3547
				} else if($wireless_mode == "11g ht") {
3548
					if(!isset($wireless_modes["11b"]))
3549
						$wireless_modes["11b"] = array();
3550
					if(!isset($wireless_modes["11g"]))
3551
						$wireless_modes["11g"] = array();
3552
					$wireless_mode = "11ng";
3553
				} else if($wireless_mode == "11a ht") {
3554
					if(!isset($wireless_modes["11a"]))
3555
						$wireless_modes["11a"] = array();
3556
					$wireless_mode = "11na";
3557
				}
3558
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3559
			}
3560
			$c++;
3561
		}
3562
	}
3563
	return($wireless_modes);
3564
}
3565

    
3566
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3567
function get_wireless_channel_info($interface) {
3568
	$wireless_channels = array();
3569

    
3570
	$wlif = get_real_interface($interface);
3571

    
3572
	if($wlif != NULL && is_interface_wireless($wlif)) {
3573
		$cloned_interface = get_real_interface($interface);
3574
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3575
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3576
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3577

    
3578
		$interface_channels = "";
3579
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3580

    
3581
		foreach ($interface_channels as $channel_line) {
3582
			$channel_line = explode(",", $channel_line);
3583
			if(!isset($wireless_channels[$channel_line[0]]))
3584
				$wireless_channels[$channel_line[0]] = $channel_line;
3585
		}
3586
	}
3587
	return($wireless_channels);
3588
}
3589

    
3590
/****f* interfaces/get_interface_mtu
3591
 * NAME
3592
 *   get_interface_mtu - Return the mtu of an interface
3593
 * RESULT
3594
 *   $tmp       - Returns the mtu of an interface
3595
 ******/
3596
function get_interface_mtu($interface) {
3597
        $mtu = pfSense_get_interface_addresses($interface);
3598
        return $mtu['mtu'];
3599
}
3600

    
3601
function get_interface_mac($interface) {
3602

    
3603
	$macinfo = pfSense_get_interface_addresses($interface);
3604
	return $macinfo["macaddr"];
3605
}
3606

    
3607
/****f* pfsense-utils/generate_random_mac_address
3608
 * NAME
3609
 *   generate_random_mac - generates a random mac address
3610
 * INPUTS
3611
 *   none
3612
 * RESULT
3613
 *   $mac - a random mac address
3614
 ******/
3615
function generate_random_mac_address() {
3616
        $mac = "02";
3617
        for($x=0; $x<5; $x++)
3618
                $mac .= ":" . dechex(rand(16, 255));
3619
        return $mac;
3620
}
3621

    
3622
/****f* interfaces/is_jumbo_capable
3623
 * NAME
3624
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3625
 * INPUTS
3626
 *   $int             - string containing interface name
3627
 * RESULT
3628
 *   boolean          - true or false
3629
 ******/
3630
function is_jumbo_capable($int) {
3631
        global $g;
3632

    
3633
        $int_family = preg_split("/[0-9]+/", $int);
3634

    
3635
        if (in_array($int_family[0], $g['vlan_long_frame']))
3636
                return true;
3637
        else
3638
                return false;
3639
}
3640

    
3641
function setup_pppoe_reset_file($pppif, $iface="") {
3642
	global $g;
3643
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3644

    
3645
	if(!empty($iface) && !empty($pppif)){
3646
		$cron_cmd = <<<EOD
3647
#!/bin/sh
3648
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
3649
/usr/bin/logger -t pppoe{$iface} "PPPoE periodic reset executed on {$iface}"
3650

    
3651
EOD;
3652

    
3653
		file_put_contents($cron_file, $cron_cmd);
3654
		chmod($cron_file, 0700);
3655
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3656
	} else
3657
		unlink_if_exists($cron_file);
3658
}
3659

    
3660
function get_vip_descr($ipaddress) {
3661
	global $config;
3662

    
3663
	foreach ($config['virtualip']['vip'] as $vip) {
3664
		if ($vip['subnet'] == $ipaddress) {
3665
			return ($vip['descr']);
3666
		}
3667
	}
3668
	return "";
3669
}
3670

    
3671
?>
(25-25/61)