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
	/* Return for unassigned interfaces. This is a minimum requirement. */
1148
	if (empty($config['interfaces'][$interface]))
1149
		return 0;
1150
	$ifcfg = $config['interfaces'][$interface];
1151
	if (!isset($ifcfg['enable']))
1152
		return 0;
1153

    
1154
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1155
	if(!is_dir("/var/spool/lock")) {
1156
		exec("/bin/mkdir -p /var/spool/lock");
1157
		exec("/bin/chmod a+rw /var/spool/lock/.");
1158
	}
1159
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files	
1160
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1161
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1162

    
1163
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1164
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1165
			if ($ifcfg['if'] == $ppp['if'])
1166
				break;
1167
		}
1168
	}
1169
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1170
		log_error("Can't find PPP config for {$ifcfg['if']} in interface_ppps_configure().");
1171
		return 0;
1172
	}
1173
	$pppif = $ifcfg['if'];
1174
	if ($ppp['type'] == "ppp")
1175
		$type = "modem";
1176
	else
1177
		$type = $ppp['type'];
1178
	$upper_type = strtoupper($ppp['type']);	
1179

    
1180
	if($g['booting']) {
1181
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1182
		echo "starting {$pppif} link...";
1183
		// Do not re-configure the interface if we are booting and it's already been started
1184
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1185
			return 0;
1186
	}
1187

    
1188
	$ports = explode(',',$ppp['ports']);
1189
	if ($type != "modem") {
1190
		foreach ($ports as $pid => $port)
1191
			$ports[$pid] = get_real_interface($port);
1192
	}
1193
	$localips = explode(',',$ppp['localip']);
1194
	$gateways = explode(',',$ppp['gateway']);
1195
	$subnets = explode(',',$ppp['subnet']);
1196

    
1197
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1198
	 * to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1199
	 */
1200
	foreach($ports as $pid => $port){
1201
		switch ($ppp['type']) {
1202
			case "pppoe": 
1203
				/* Bring the parent interface up */
1204
				interfaces_bring_up($port);
1205
				pfSense_ngctl_attach(".", $port);
1206
				break;
1207
			case "pptp":
1208
			case "l2tp":
1209
				/* configure interface */
1210
				if(is_ipaddr($localips[$pid])){
1211
					// Manually configure interface IP/subnet
1212
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1213
					interfaces_bring_up($port);
1214
				} else if (empty($localips[$pid]))
1215
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1216
				
1217
				if(!is_ipaddr($localips[$pid])){
1218
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure. Using 0.0.0.0 ip!");
1219
					$localips[$pid] = "0.0.0.0";
1220
				}
1221
				/* XXX: This needs to go away soon! [It's commented out!] */
1222
				/* Configure the gateway (remote IP ) */
1223
				if (!$g['booting'] && !is_ipaddr($gateways[$pid]) && is_hostname($gateways[$pid])) {
1224
					/* XXX: Fix later 
1225
					$gateways[$pid] = gethostbyname($gateways[$pid]);
1226
					if(!is_ipaddr($gateways[$pid])) {
1227
						log_error("Could not get a valid Gateway IP from {$port} via DNS in interfaces_ppps_configure.");
1228
						return 0;
1229
					}
1230
					*/
1231
				}
1232
				if(!is_ipaddr($gateways[$pid])){
1233
					log_error("Could not get a PPTP/L2TP Remote IP address from {$dhcp_gateway} for {$gway} in interfaces_ppps_configure.");
1234
					return 0;
1235
				}
1236
				pfSense_ngctl_attach(".", $port);
1237
				break;
1238
			case "ppp":
1239
				if (!file_exists("{$port}")) {
1240
					log_error("Device {$port} does not exist. PPP link cannot start without the modem device.");
1241
					return 0;
1242
				}
1243
				break;
1244
			default:
1245
				log_error("Unkown {$type} configured as ppp interface.");
1246
				break;
1247
		}
1248
	}
1249
	
1250
	if (is_array($ports) && count($ports) > 1)
1251
		$multilink = "enable";
1252
	else
1253
		$multilink = "disable";
1254
	
1255
	if ($type == "modem"){
1256
		if (is_ipaddr($ppp['localip']))
1257
			$localip = $ppp['localip'];
1258
		else
1259
			$localip = '0.0.0.0';
1260

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

    
1272
	if (isset($ppp['ondemand'])) 
1273
		$ondemand = "enable";
1274
	else
1275
		$ondemand = "disable";
1276
	if (!isset($ppp['idletimeout']))
1277
		$ppp['idletimeout'] = 0;
1278

    
1279
	if (empty($ppp['username']) && $type == "modem"){
1280
		$ppp['username'] = "user";
1281
		$ppp['password'] = "none";
1282
	}
1283
	if (empty($ppp['password']) && $type == "modem")
1284
		$passwd = "none";
1285
	else
1286
		$passwd = base64_decode($ppp['password']);
1287

    
1288
	$bandwidths = explode(',',$ppp['bandwidth']);
1289
	$mtus = explode(',',$ppp['mtu']);
1290
	$mrus = explode(',',$ppp['mru']);
1291

    
1292
	if (isset($ppp['mrru']))
1293
		$mrrus = explode(',',$ppp['mrru']);
1294

    
1295
	// Construct the mpd.conf file
1296
	$mpdconf = <<<EOD
1297
startup:
1298
	# configure the console
1299
	set console close
1300
	# configure the web server
1301
	set web close
1302

    
1303
default:
1304
{$ppp['type']}client:
1305
	create bundle static {$interface}
1306
	set iface name {$pppif}
1307

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

    
1328
EOD;
1329
	}
1330
	$mpdconf .= <<<EOD
1331
	set iface {$ondemand} on-demand
1332
	set iface idle {$ppp['idletimeout']}
1333

    
1334
EOD;
1335

    
1336
	if (isset($ppp['ondemand']))
1337
		$mpdconf .= <<<EOD
1338
	set iface addrs 10.10.1.1 10.10.1.2
1339

    
1340
EOD;
1341
	
1342
	if (isset($ppp['tcpmssfix']))
1343
		$tcpmss = "disable";
1344
	else
1345
		$tcpmss = "enable";
1346
		$mpdconf .= <<<EOD
1347
	set iface {$tcpmss} tcpmssfix
1348

    
1349
EOD;
1350

    
1351
	$mpdconf .= <<<EOD
1352
	set iface up-script /usr/local/sbin/ppp-linkup
1353
	set iface down-script /usr/local/sbin/ppp-linkdown
1354
	set ipcp ranges {$ranges}
1355

    
1356
EOD;
1357
	if (isset($ppp['vjcomp']))
1358
		$mpdconf .= <<<EOD
1359
	set ipcp no vjcomp
1360

    
1361
EOD;
1362

    
1363
	if (isset($config['system']['dnsallowoverride']))
1364
		$mpdconf .= <<<EOD
1365
	set ipcp enable req-pri-dns
1366
	set ipcp enable req-sec-dns
1367

    
1368
EOD;
1369
	if (!isset($ppp['verbose_log']))
1370
		$mpdconf .= <<<EOD
1371
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1372

    
1373
EOD;
1374
	foreach($ports as $pid => $port){
1375
		$port = get_real_interface($port);
1376
		$mpdconf .= <<<EOD
1377

    
1378
	create link static {$interface}_link{$pid} {$type}
1379
	set link action bundle {$interface}
1380
	set link {$multilink} multilink
1381
	set link keep-alive 10 60
1382
	set link max-redial 0
1383

    
1384
EOD;
1385
		if (isset($ppp['shortseq']))
1386
			$mpdconf .= <<<EOD
1387
	set link no shortseq
1388

    
1389
EOD;
1390

    
1391
		if (isset($ppp['acfcomp']))
1392
			$mpdconf .= <<<EOD
1393
	set link no acfcomp
1394

    
1395
EOD;
1396

    
1397
		if (isset($ppp['protocomp']))
1398
			$mpdconf .= <<<EOD
1399
	set link no protocomp
1400

    
1401
EOD;
1402

    
1403
		$mpdconf .= <<<EOD
1404
	set link disable chap pap
1405
	set link accept chap pap eap
1406
	set link disable incoming
1407

    
1408
EOD;
1409

    
1410

    
1411
		if (!empty($bandwidths[$pid]))
1412
			$mpdconf .= <<<EOD
1413
	set link bandwidth {$bandwidths[$pid]}
1414

    
1415
EOD;
1416

    
1417
		if (empty($mtus[$pid]))
1418
			$mtus[$pid] = "1492";
1419
			$mpdconf .= <<<EOD
1420
	set link mtu {$mtus[$pid]}
1421

    
1422
EOD;
1423

    
1424
		if (!empty($mrus[$pid]))
1425
			$mpdconf .= <<<EOD
1426
	set link mru {$mrus[$pid]}
1427

    
1428
EOD;
1429

    
1430
		if (!empty($mrrus[$pid]))
1431
			$mpdconf .= <<<EOD
1432
	set link mrru {$mrrus[$pid]}
1433

    
1434
EOD;
1435

    
1436
		$mpdconf .= <<<EOD
1437
	set auth authname "{$ppp['username']}"
1438
	set auth password {$passwd}
1439

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

    
1450
EOD;
1451
		}
1452
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1453
			$mpdconf .= <<<EOD
1454
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1455

    
1456
EOD;
1457
		}
1458
		if (isset($ppp['initstr']) && $type == "modem") {
1459
			$initstr = base64_decode($ppp['initstr']);
1460
			$mpdconf .= <<<EOD
1461
	set modem var \$InitString "{$initstr}"
1462

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

    
1470
EOD;
1471
		}
1472
		if (isset($ppp['apn']) && $type == "modem") {
1473
			$mpdconf .= <<<EOD
1474
	set modem var \$APN "{$ppp['apn']}"
1475
	set modem var \$APNum "{$ppp['apnum']}"
1476

    
1477
EOD;
1478
		}
1479
		if (isset($ppp['provider']) && $type == "pppoe") {
1480
			$mpdconf .= <<<EOD
1481
	set pppoe service "{$ppp['provider']}"
1482

    
1483
EOD;
1484
		}
1485
		if ($type == "pppoe")
1486
			$mpdconf .= <<<EOD
1487
	set pppoe iface {$port}
1488

    
1489
EOD;
1490

    
1491
		if ($type == "pptp" || $type == "l2tp") {
1492
			$mpdconf .= <<<EOD
1493
	set {$type} self {$localips[$pid]}
1494
	set {$type} peer {$gateways[$pid]}
1495

    
1496
EOD;
1497
		}
1498
		
1499
		$mpdconf .= "\topen\r\n";
1500
	} //end foreach($port)
1501

    
1502

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

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

    
1532
	/* fire up mpd */
1533
	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");
1534

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

    
1543
	return 1;
1544
}
1545

    
1546
function interfaces_carp_setup() {
1547
	global $g, $config;
1548

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

    
1557
	// Prepare CmdCHAIN that will be used to execute commands.
1558
	$cmdchain = new CmdCHAIN();	
1559

    
1560
	if ($g['booting']) {
1561
		echo "Configuring CARP settings...";
1562
		mute_kernel_msgs();
1563
	}
1564

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

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

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

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

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

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

    
1624
	$cmdchain->execute();
1625
	$cmdchain->clear();
1626

    
1627
	if ($g['booting']) {
1628
		unmute_kernel_msgs();
1629
		echo "done.\n";
1630
	}
1631
}
1632

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

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

    
1649
	$paa = array();
1650
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1651

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

    
1663
				if (!is_array($paa[$proxyif]))
1664
					$paa[$proxyif] = array();
1665

    
1666
				$paa[$proxyif][] = $vipent;
1667
			}
1668
		}
1669
	}
1670

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

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

    
1747
function interface_ipalias_configure(&$vip) {
1748

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

    
1755
function interface_reload_carps($cif) {
1756
	global $config;
1757

    
1758
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1759
	if (empty($carpifs))
1760
		return;
1761

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

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

    
1796
	if ($vip['mode'] != "carp")
1797
		return;
1798

    
1799
	$vip_password = $vip['password'];
1800
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1801
	if ($vip['password'] != "")
1802
		$password = " pass {$vip_password}";
1803

    
1804
	// set the vip interface to the vhid
1805
	$vipif = "vip{$vip['vhid']}";
1806

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

    
1817
	/* Ensure CARP IP really exists prior to loading up. */
1818
	$ww_subnet_ip = find_interface_ip($realif);
1819
	$ww_subnet_bits = find_interface_subnet($realif);
1820
	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'])) {
1821
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1822
		return;
1823
	}
1824

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

    
1834
	/* invalidate interface cache */
1835
	get_interface_arr(true);
1836

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

    
1843
	interfaces_bring_up($vipif);
1844
	
1845
	return $vipif;
1846
}
1847

    
1848
function interface_carpdev_configure(&$vip) {
1849
	global $g;
1850

    
1851
	if ($vip['mode'] != "carpdev-dhcp")
1852
		return;
1853

    
1854
	$vip_password = $vip['password'];
1855
	$vip_password = str_replace(" ", "", $vip_password);
1856
	if($vip['password'] != "")
1857
		$password = " pass \"" . $vip_password . "\"";
1858

    
1859
	if (empty($vip['interface']))
1860
		return;
1861

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

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

    
1882
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} advbase {$vip['advbase']} {$password}");
1883
	interfaces_bring_up($vipif);
1884

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

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

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

    
1908
EOD;
1909

    
1910
		fwrite($fd, $dhclientconf);
1911
		fclose($fd);
1912

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

    
1920
	return $vipif;
1921
}
1922

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

    
1964
	if($needs_clone == true) {
1965
		/* remove previous instance if it exists */
1966
		if(does_interface_exist($realif))
1967
			pfSense_interface_destroy($realif);
1968

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

    
1987
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1988
	global $config, $g;
1989

    
1990
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
1991
	                         'diversity', 'txantenna', 'rxantenna', 'distance',
1992
	                         'regdomain', 'regcountry', 'reglocation');
1993

    
1994
	if(!is_interface_wireless($ifcfg['if']))
1995
		return;
1996

    
1997
	$baseif = interface_get_wireless_base($ifcfg['if']);
1998

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

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

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

    
2056
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2057
	global $config, $g;
2058

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

    
2066
	// Remove script file
2067
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2068

    
2069
	// Clone wireless nic if needed.
2070
	interface_wireless_clone($if, $wl);
2071

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

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

    
2079
	/* set values for /path/program */
2080
	$hostapd = "/usr/sbin/hostapd";
2081
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2082
	$ifconfig = "/sbin/ifconfig";
2083
	$sysctl = "/sbin/sysctl";
2084
	$killall = "/usr/bin/killall";
2085

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

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

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

    
2101
	/* Set ssid */
2102
	if($wlcfg['ssid'])
2103
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2104

    
2105
	/* Set 802.11g protection mode */
2106
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2107

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

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

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

    
2125
	/* Set rxantenna value */
2126
	if(isset($wlcfg['rxantenna']))
2127
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2128

    
2129
	/* set Distance value */
2130
	if($wlcfg['distance'])
2131
		$distance = escapeshellarg($wlcfg['distance']);
2132

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

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

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

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

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

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

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

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

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

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

    
2221
	mwexec(kill_hostapd("{$if}"));
2222
	mwexec(kill_wpasupplicant("{$if}"));
2223

    
2224
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2225
	conf_mount_rw();
2226

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

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

    
2281
EOD;
2282

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

    
2289
EOD;
2290

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

    
2298
ieee8021x=1
2299
auth_server_addr={$wlcfg['auth_server_addr']}
2300
auth_server_port={$auth_server_port}
2301
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2302

    
2303
EOD;
2304
				} else {
2305
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2306
				}
2307

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

    
2312
			}
2313
			break;
2314
	}
2315

    
2316
	/*
2317
	 *    all variables are set, lets start up everything
2318
	 */
2319

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

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

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

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

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

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

    
2366
	fclose($fd_set);
2367
	conf_mount_ro();
2368

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

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

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

    
2394
		/* set country */
2395
		if($wlcfg['regcountry'])
2396
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2397

    
2398
		/* set location */
2399
		if($wlcfg['reglocation'])
2400
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2401

    
2402
		$wlregcmd_args = implode(" ", $wlregcmd);
2403

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

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

    
2425
		/* apply the regulatory settings */
2426
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2427

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

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

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

    
2452
	/* configure wireless */
2453
	$wlcmd_args = implode(" ", $wlcmd);
2454
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2455

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

    
2461
	return 0;
2462

    
2463
}
2464

    
2465
function kill_hostapd($interface) {
2466
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2467
}
2468

    
2469
function kill_wpasupplicant($interface) {
2470
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2471
}
2472

    
2473
function find_dhclient_process($interface) {
2474
	if ($interface)
2475
		$pid = `/bin/pgrep -axf "dhclient: {$interface}"`;
2476
	else
2477
		$pid = 0;
2478

    
2479
	return intval($pid);
2480
}
2481

    
2482
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2483
	global $config, $g;
2484
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2485

    
2486
	$wancfg = $config['interfaces'][$interface];
2487

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

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

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

    
2509
	/* wireless configuration? */
2510
	if (is_array($wancfg['wireless']))
2511
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2512

    
2513
	if ($wancfg['spoofmac']) {
2514
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2515
			" link " . escapeshellarg($wancfg['spoofmac']));
2516

    
2517
                /*
2518
                 * All vlans need to spoof their parent mac address, too.  see
2519
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2520
                 */
2521
                if (is_array($config['vlans']['vlan'])) {
2522
                        foreach ($config['vlans']['vlan'] as $vlan) {
2523
                                if ($vlan['if'] == $realhwif)
2524
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2525
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2526
                        }
2527
                }
2528
	}  else {
2529
		$mac = get_interface_mac($realhwif);
2530
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2531
			/*   this is not a valid mac address.  generate a
2532
			 *   temporary mac address so the machine can get online.
2533
			 */
2534
			echo "Generating new MAC address.";
2535
			$random_mac = generate_random_mac_address();
2536
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2537
				" link " . escapeshellarg($random_mac));
2538
			$wancfg['spoofmac'] = $random_mac;
2539
			write_config();
2540
			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");
2541
		}
2542
	}
2543

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

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

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

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

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

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

    
2606
	/* invalidate interface/ip/sn cache */
2607
	get_interface_arr(true);
2608
	unset($interface_ip_arr_cache[$realif]);
2609
	unset($interface_sn_arr_cache[$realif]);
2610

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

    
2645
	if(does_interface_exist($wancfg['if']))
2646
		interfaces_bring_up($wancfg['if']);
2647

    
2648
	interface_netgraph_needed($interface);
2649
 	
2650
	if (!$g['booting']) {
2651
		link_interface_to_vips($interface, "update");
2652

    
2653
		unset($gre);
2654
		$gre = link_interface_to_gre($interface);
2655
		if (!empty($gre))
2656
			array_walk($gre, 'interface_gre_configure');
2657

    
2658
		unset($gif);
2659
		$gif = link_interface_to_gif($interface);
2660
		if (!empty($gif))
2661
                       	array_walk($gif, 'interface_gif_configure');
2662

    
2663
		if ($linkupevent == false) {
2664
			unset($bridgetmp);
2665
			$bridgetmp = link_interface_to_bridge($interface);
2666
			if (!empty($bridgetmp))
2667
				interface_bridge_add_member($bridgetmp, $realif);
2668
		}
2669

    
2670
		$grouptmp = link_interface_to_group($interface);
2671
		if (!empty($grouptmp))
2672
			array_walk($grouptmp, 'interface_group_add_member');
2673

    
2674
		if ($interface == "lan")
2675
			/* make new hosts file */
2676
			system_hosts_generate();
2677

    
2678
		if ($reloadall == true) {
2679

    
2680
			/* reconfigure static routes (kernel may have deleted them) */
2681
			system_routing_configure($interface);
2682

    
2683
			/* reload ipsec tunnels */
2684
			vpn_ipsec_configure();
2685

    
2686
			/* restart dnsmasq */
2687
			services_dnsmasq_configure();
2688

    
2689
			/* update dyndns */
2690
			send_event("service reload dyndns {$interface}");
2691

    
2692
			/* reload captive portal */
2693
			captiveportal_init_rules();
2694
		}
2695
	}
2696

    
2697
	return 0;
2698
}
2699

    
2700
function interface_carpdev_dhcp_configure($interface = "wan") {
2701
	global $config, $g;
2702

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

    
2711
	return 0;
2712
}
2713

    
2714
function interface_dhcp_configure($interface = "wan") {
2715
	global $config, $g;
2716

    
2717
	$wancfg = $config['interfaces'][$interface];
2718
	if (empty($wancfg))
2719
		$wancfg = array();
2720

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

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

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

    
2752
EOD;
2753

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

    
2763
EOD;
2764
}
2765
	fwrite($fd, $dhclientconf);
2766
	fclose($fd);
2767

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

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

    
2777
	return 0;
2778
}
2779

    
2780
function interfaces_group_setup() {
2781
	global $config;
2782

    
2783
	if (!is_array($config['ifgroups']['ifgroupentry']))
2784
		return;
2785

    
2786
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2787
		interface_group_setup($groupar);
2788

    
2789
	return;
2790
}
2791

    
2792
function interface_group_setup(&$groupname /* The parameter is an array */) {
2793
	global $config;
2794

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

    
2804
	return;
2805
}
2806

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

    
2817
/* COMPAT Function */
2818
function get_real_wan_interface($interface = "wan") {
2819
	return get_real_interface($interface);
2820
}
2821

    
2822
/* COMPAT Function */
2823
function get_current_wan_address($interface = "wan") {
2824
	return get_interface_ip($interface);
2825
}
2826

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

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

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

    
2847
        foreach ($ifdescrs as $if => $ifname) {
2848
                if ($config['interfaces'][$if]['if'] == $interface)
2849
                        return $if;
2850

    
2851
                if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
2852
                        return $if;
2853

    
2854
		// XXX: This case doesn't work anymore (segfaults - recursion?) - should be replaced with something else or just removed.
2855
		//      Not to be replaced with get_real_interface - causes slow interface listings here because of recursion!
2856
		/*
2857
                $int = get_parent_interface($if);
2858
                if ($int[0] == $interface)
2859
                        return $ifname;
2860
		*/
2861
        }
2862
        return NULL;
2863
}
2864

    
2865
/* attempt to resolve interface to friendly descr */
2866
function convert_friendly_interface_to_friendly_descr($interface) {
2867
        global $config;
2868

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

    
2913
        return $ifdesc;
2914
}
2915

    
2916
function convert_real_interface_to_friendly_descr($interface) {
2917
        global $config;
2918

    
2919
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2920

    
2921
        if ($ifdesc) {
2922
                $iflist = get_configured_interface_with_descr(false, true);
2923
                return $iflist[$ifdesc];
2924
        }
2925

    
2926
        return $interface;
2927
}
2928

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

    
2941
	$parents = array();
2942
	//Check that we got a valid interface passed
2943
	$realif = get_real_interface($interface);
2944
	if ($realif == NULL)
2945
		return $parents;
2946

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

    
2989
function interface_is_wireless_clone($wlif) {
2990
	if(!stristr($wlif, "_wlan")) {
2991
		return false;
2992
	} else {
2993
		return true;
2994
	}
2995
}
2996

    
2997
function interface_get_wireless_base($wlif) {
2998
	if(!stristr($wlif, "_wlan")) {
2999
		return $wlif;
3000
	} else {
3001
		return substr($wlif, 0, stripos($wlif, "_wlan"));
3002
	}
3003
}
3004

    
3005
function interface_get_wireless_clone($wlif) {
3006
	if(!stristr($wlif, "_wlan")) {
3007
		return $wlif . "_wlan0";
3008
	} else {
3009
		return $wlif;
3010
	}
3011
}
3012

    
3013
function get_real_interface($interface = "wan") {
3014
    global $config;
3015

    
3016
	$wanif = NULL;
3017

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

    
3050
		$cfg = &$config['interfaces'][$interface];
3051

    
3052
		// Wireless cloned NIC support (FreeBSD 8+)
3053
		// interface name format: $parentnic_wlanparentnic#
3054
		// example: ath0_wlan0
3055
		if (is_interface_wireless($cfg['if'])) {
3056
			$wanif = interface_get_wireless_clone($cfg['if']);
3057
			break;
3058
		}
3059
		/*
3060
		if (empty($cfg['if'])) {
3061
			$wancfg = $cfg['if'];
3062
			break;
3063
		}
3064
		*/
3065

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

    
3092
    return $wanif;
3093
}
3094

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

    
3117
/*
3118
 * find_ip_interface($ip): return the interface where an ip is defined
3119
 */
3120
function find_ip_interface($ip)
3121
{
3122
        /* if list */
3123
        $ifdescrs = get_configured_interface_list();
3124

    
3125
        foreach ($ifdescrs as $ifdescr => $ifname) {
3126
		if ($ip == get_interface_ip($ifname)) {
3127
                	$int = get_real_interface($ifname);
3128
			return $int;
3129
		}
3130
        }
3131
        return false;
3132
}
3133

    
3134
/*
3135
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
3136
 */
3137
function find_number_of_created_carp_interfaces() {
3138
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
3139
}
3140

    
3141
function get_all_carp_interfaces() {
3142
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
3143
	$ints = explode(" ", $ints);
3144
	return $ints;
3145
}
3146

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

    
3164
function link_carp_interface_to_parent($interface) {
3165
        global $config;
3166

    
3167
        if ($interface == "")
3168
                return;
3169

    
3170
        $carp_ip = get_interface_ip($interface);
3171
        if (!is_ipaddr($carp_ip))
3172
                return;
3173

    
3174
        /* if list */
3175
        $ifdescrs = get_configured_interface_list();
3176
        foreach ($ifdescrs as $ifdescr => $ifname) {
3177
                $interfaceip = get_interface_ip($ifname);
3178
                $subnet_bits = get_interface_subnet($ifname);
3179
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
3180
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
3181
                        return $ifname;
3182
        }
3183

    
3184
        return "";
3185
}
3186

    
3187
/****f* interfaces/link_ip_to_carp_interface
3188
 * NAME
3189
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
3190
 * INPUTS
3191
 *   $ip
3192
 * RESULT
3193
 *   $carp_ints
3194
 ******/
3195
function link_ip_to_carp_interface($ip) {
3196
        global $config;
3197

    
3198
        if (!is_ipaddr($ip))
3199
                return;
3200

    
3201
        $carp_ints = "";
3202
        if (is_array($config['virtualip']['vip'])) {
3203
		$first = 0;
3204
		$carp_int = array();
3205
                foreach ($config['virtualip']['vip'] as $vip) {
3206
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3207
                                $carp_ip = $vip['subnet'];
3208
                                $carp_sn = $vip['subnet_bits'];
3209
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
3210
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
3211
					$carp_int[] = "vip{$vip['vhid']}";
3212
                        }
3213
                }
3214
		if (!empty($carp_int))
3215
			$carp_ints = implode(" ", array_unique($carp_int));
3216
        }
3217

    
3218
        return $carp_ints;
3219
}
3220

    
3221
function link_interface_to_vlans($int, $action = "") {
3222
	global $config;
3223

    
3224
	if (empty($int))
3225
		return;
3226

    
3227
	if (is_array($config['vlans']['vlan'])) {
3228
                foreach ($config['vlans']['vlan'] as $vlan) {
3229
			if ($int == $vlan['if']) {
3230
				if ($action == "update") {
3231
					interfaces_bring_up($int);
3232
				} else if ($action == "")
3233
					return $vlan;
3234
			}
3235
		}
3236
	}
3237
}
3238

    
3239
function link_interface_to_vips($int, $action = "") {
3240
        global $config;
3241

    
3242
        if (is_array($config['virtualip']['vip'])) {
3243
		foreach ($config['virtualip']['vip'] as $vip) {
3244
			if ($int == $vip['interface']) {
3245
				if ($action == "update") {
3246
					interface_vip_bring_down($vip);
3247
					interfaces_vips_configure($int);
3248
				} else
3249
					return $vip;
3250
			}
3251
		}
3252
	}
3253
}
3254

    
3255
/****f* interfaces/link_interface_to_bridge
3256
 * NAME
3257
 *   link_interface_to_bridge - Finds out a bridge group for an interface
3258
 * INPUTS
3259
 *   $ip
3260
 * RESULT
3261
 *   bridge[0-99]
3262
 ******/
3263
function link_interface_to_bridge($int) {
3264
        global $config;
3265

    
3266
        if (is_array($config['bridges']['bridged'])) {
3267
                foreach ($config['bridges']['bridged'] as $bridge) {
3268
			if (in_array($int, explode(',', $bridge['members'])))
3269
                                return "{$bridge['bridgeif']}";
3270
		}
3271
	}
3272
}
3273

    
3274
function link_interface_to_group($int) {
3275
        global $config;
3276

    
3277
	$result = array();
3278

    
3279
        if (is_array($config['ifgroups']['ifgroupentry'])) {
3280
                foreach ($config['ifgroups']['ifgroupentry'] as $group) {
3281
			if (in_array($int, explode(" ", $group['members'])))
3282
				$result[$group['ifname']] = $int;
3283
		}
3284
	}
3285

    
3286
	return $result;
3287
}
3288

    
3289
function link_interface_to_gre($interface) {
3290
        global $config;
3291

    
3292
	$result = array();
3293

    
3294
        if (is_array($config['gres']['gre'])) {
3295
                foreach ($config['gres']['gre'] as $gre)
3296
                        if($gre['if'] == $interface)
3297
				$result[] = $gre;
3298
	}
3299

    
3300
	return $result;
3301
}
3302

    
3303
function link_interface_to_gif($interface) {
3304
        global $config;
3305

    
3306
	$result = array();
3307

    
3308
        if (is_array($config['gifs']['gif'])) {
3309
                foreach ($config['gifs']['gif'] as $gif)
3310
                        if($gif['if'] == $interface)
3311
                                $result[] = $gif;
3312
	}
3313

    
3314
	return $result;
3315
}
3316

    
3317
/*
3318
 * find_interface_ip($interface): return the interface ip (first found)
3319
 */
3320
function find_interface_ip($interface, $flush = false)
3321
{
3322
	global $interface_ip_arr_cache;
3323
	global $interface_sn_arr_cache;
3324

    
3325
	$interface = str_replace("\n", "", $interface);
3326
	
3327
	if (!does_interface_exist($interface))
3328
		return;
3329

    
3330
	/* Setup IP cache */
3331
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
3332
		$ifinfo = pfSense_get_interface_addresses($interface);
3333
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3334
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3335
	}
3336

    
3337
	return $interface_ip_arr_cache[$interface];
3338
}
3339

    
3340
function find_interface_subnet($interface, $flush = false)
3341
{
3342
	global $interface_sn_arr_cache;
3343
	global $interface_ip_arr_cache;
3344

    
3345
	$interface = str_replace("\n", "", $interface);
3346
	if (does_interface_exist($interface) == false)
3347
		return;
3348

    
3349
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
3350
		$ifinfo = pfSense_get_interface_addresses($interface);
3351
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3352
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3353
        }
3354

    
3355
	return $interface_sn_arr_cache[$interface];
3356
}
3357

    
3358
function ip_in_interface_alias_subnet($interface, $ipalias) {
3359
	global $config;
3360

    
3361
	if (empty($interface) || !is_ipaddr($ipalias))
3362
		return false;
3363
	if (is_array($config['virtualip']['vip'])) {
3364
                foreach ($config['virtualip']['vip'] as $vip) {
3365
                        switch ($vip['mode']) {
3366
                        case "ipalias":
3367
                                if ($vip['interface'] <> $interface)
3368
                                        break;
3369
				if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']))
3370
					return true;
3371
                                break;
3372
                        }
3373
                }
3374
	}
3375

    
3376
	return false;
3377
}
3378

    
3379
function get_interface_ip($interface = "wan")
3380
{
3381
	$realif = get_real_interface($interface);
3382
	if (!$realif) {
3383
		if (preg_match("/^carp/i", $interface))
3384
			$realif = $interface;
3385
		else if (preg_match("/^vip/i", $interface))
3386
			$realif = $interface;
3387
		else
3388
			return null;
3389
	}
3390

    
3391
	$curip = find_interface_ip($realif);
3392
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
3393
		return $curip;
3394
	else
3395
		return null;
3396
}
3397

    
3398
function get_interface_subnet($interface = "wan")
3399
{
3400
	$realif = get_real_interface($interface);
3401
	if (!$realif) {
3402
                if (preg_match("/^carp/i", $interface))
3403
                        $realif = $interface;
3404
                else if (preg_match("/^vip/i", $interface))
3405
                        $realif = $interface;
3406
                else
3407
                        return null;
3408
        }
3409

    
3410
	$cursn = find_interface_subnet($realif);
3411
	if (!empty($cursn))
3412
		return $cursn;
3413

    
3414
	return null;
3415
}
3416

    
3417
/* return outside interfaces with a gateway */
3418
function get_interfaces_with_gateway() {
3419
	global $config;
3420

    
3421
	$ints = array();
3422

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

    
3445
/* return true if interface has a gateway */
3446
function interface_has_gateway($friendly) {
3447
	global $config;
3448

    
3449
	if (!empty($config['interfaces'][$friendly])) {
3450
		$ifname = &$config['interfaces'][$friendly];
3451
		switch ($ifname['ipaddr']) {
3452
			case "dhcp":
3453
			case "carpdev-dhcp":
3454
			case "pppoe":
3455
			case "pptp":
3456
			case "l2tp":
3457
			case "ppp";
3458
				return true;
3459
			break;
3460
			default:
3461
				if (substr($ifname['if'], 0, 5) ==  "ovpnc")
3462
					return true;
3463
				if (!empty($ifname['gateway']))
3464
					return true;
3465
			break;
3466
		}
3467
	}
3468

    
3469
	return false;
3470
}
3471

    
3472
/****f* interfaces/is_altq_capable
3473
 * NAME
3474
 *   is_altq_capable - Test if interface is capable of using ALTQ
3475
 * INPUTS
3476
 *   $int            - string containing interface name
3477
 * RESULT
3478
 *   boolean         - true or false
3479
 ******/
3480

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

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

    
3496
        if (in_array($int_family[0], $capable))
3497
                return true;
3498
	else if (stristr($int, "vlan")) /* VLANs are name $parent_$vlan now */
3499
		return true;
3500
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
3501
		return true;
3502
        else
3503
                return false;
3504
}
3505

    
3506
/****f* interfaces/is_interface_wireless
3507
 * NAME
3508
 *   is_interface_wireless - Returns if an interface is wireless
3509
 * RESULT
3510
 *   $tmp       - Returns if an interface is wireless
3511
 ******/
3512
function is_interface_wireless($interface) {
3513
        global $config, $g;
3514

    
3515
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3516
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3517
                if (preg_match($g['wireless_regex'], $interface)) {
3518
                        if (isset($config['interfaces'][$friendly]))
3519
                                $config['interfaces'][$friendly]['wireless'] = array();
3520
                        return true;
3521
                }
3522
                return false;
3523
        } else
3524
                return true;
3525
}
3526

    
3527
function get_wireless_modes($interface) {
3528
	/* return wireless modes and channels */
3529
	$wireless_modes = array();
3530

    
3531
	$cloned_interface = get_real_interface($interface);
3532

    
3533
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
3534
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3535
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3536
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3537

    
3538
		$interface_channels = "";
3539
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3540
		$interface_channel_count = count($interface_channels);
3541

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

    
3572
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3573
function get_wireless_channel_info($interface) {
3574
	$wireless_channels = array();
3575

    
3576
	$cloned_interface = get_real_interface($interface);
3577

    
3578
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
3579
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3580
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3581
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3582

    
3583
		$interface_channels = "";
3584
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3585

    
3586
		foreach ($interface_channels as $channel_line) {
3587
			$channel_line = explode(",", $channel_line);
3588
			if(!isset($wireless_channels[$channel_line[0]]))
3589
				$wireless_channels[$channel_line[0]] = $channel_line;
3590
		}
3591
	}
3592
	return($wireless_channels);
3593
}
3594

    
3595
/****f* interfaces/get_interface_mtu
3596
 * NAME
3597
 *   get_interface_mtu - Return the mtu of an interface
3598
 * RESULT
3599
 *   $tmp       - Returns the mtu of an interface
3600
 ******/
3601
function get_interface_mtu($interface) {
3602
        $mtu = pfSense_get_interface_addresses($interface);
3603
        return $mtu['mtu'];
3604
}
3605

    
3606
function get_interface_mac($interface) {
3607

    
3608
	$macinfo = pfSense_get_interface_addresses($interface);
3609
	return $macinfo["macaddr"];
3610
}
3611

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

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

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

    
3640
        if (in_array($int_family[0], $g['vlan_long_frame']))
3641
                return true;
3642
        else
3643
                return false;
3644
}
3645

    
3646
function setup_pppoe_reset_file($pppif, $iface="") {
3647
	global $g;
3648
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3649

    
3650
	if(!empty($iface) && !empty($pppif)){
3651
		$cron_cmd = <<<EOD
3652
#!/bin/sh
3653
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
3654
/usr/bin/logger -t pppoe{$iface} "PPPoE periodic reset executed on {$iface}"
3655

    
3656
EOD;
3657

    
3658
		file_put_contents($cron_file, $cron_cmd);
3659
		chmod($cron_file, 0700);
3660
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3661
	} else
3662
		unlink_if_exists($cron_file);
3663
}
3664

    
3665
function get_vip_descr($ipaddress) {
3666
	global $config;
3667

    
3668
	foreach ($config['virtualip']['vip'] as $vip) {
3669
		if ($vip['subnet'] == $ipaddress) {
3670
			return ($vip['descr']);
3671
		}
3672
	}
3673
	return "";
3674
}
3675

    
3676
?>
(25-25/61)