Project

General

Profile

Download (92.7 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:	/usr/sbin/pppd	/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();
81
	if (in_array($interface, $ints))
82
		return true;
83
	else
84
		return false;
85
}
86

    
87
function interfaces_loopback_configure() {
88
	if($g['booting'])
89
		echo "Configuring loopback interface...";
90
	pfSense_interface_setaddress("lo0", "127.0.0.1");
91
	interfaces_bring_up("lo0");
92
	exec("/sbin/route add 127.0.0.2 127.0.0.1");
93
	if($g['booting'])
94
		echo "done.\n";
95
	return 0;
96
}
97

    
98
function interfaces_vlan_configure() {
99
	global $config, $g;
100
	if($g['booting'])
101
		echo "Configuring VLAN interfaces...";
102
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
103
		foreach ($config['vlans']['vlan'] as $vlan) {
104
			if(empty($vlan['vlanif']))
105
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
106
			/* XXX: Maybe we should report any errors?! */
107
			interface_vlan_configure($vlan);
108
		}
109
	}
110
	if($g['booting'])
111
		echo "done.\n";
112
}
113

    
114
function interface_vlan_configure(&$vlan) {
115
        global $config, $g;
116

    
117
	if (!is_array($vlan)) {
118
		log_error("VLAN: called with wrong options. Problems with config!");
119
		return;
120
	}
121
	$if = $vlan['if'];
122
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
123
	$tag = $vlan['tag'];
124

    
125
	if (empty($if)) {
126
		log_error("interface_vlan_confgure called with if undefined.");
127
		return;
128
	}
129

    
130
	/* make sure the parent interface is up */
131
	interfaces_bring_up($if);
132
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
133
	pfSense_interface_capabilities($if, IFCAP_VLAN_HWTAGGING|IFCAP_VLAN_MTU|IFCAP_VLAN_HWFILTER);
134

    
135
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
136
		interface_bring_down($vlanif);
137
	} else {
138
		$tmpvlanif = pfSense_interface_create("vlan");
139
		pfSense_interface_rename($tmpvlanif, $vlanif);
140
		pfSense_ngctl_name("{$tmpvlanif}:", $vlanif);
141
	}
142

    
143
	pfSense_vlan_create($vlanif, $if, $tag);
144

    
145
	interfaces_bring_up($vlanif);
146

    
147
	/* invalidate interface cache */
148
	get_interface_arr(true);
149

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

    
153
	return $vlanif;
154
}
155

    
156
function interface_qinq_configure(&$vlan, $fd = NULL) {
157
        global $config, $g;
158

    
159
        if (!is_array($vlan)) {
160
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
161
                return;
162
        }
163

    
164
        $qinqif = $vlan['if'];
165
        $tag = $vlan['tag'];
166
        if(empty($qinqif)) {
167
                log_error("interface_qinq_confgure called with if undefined.\n");
168
                return;
169
        }
170
	$vlanif = interface_vlan_configure($vlan);
171

    
172
        if ($fd == NULL) {
173
                $exec = true;
174
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
175
        } else
176
                $exec = false;
177
        /* make sure the parent is converted to ng_vlan(4) and is up */
178
        interfaces_bring_up($qinqif);
179

    
180
        if (!empty($vlanif) && does_interface_exist($vlanif)) {
181
                fwrite($fd, "shutdown {$qinqif}qinq:\n");
182
                exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
183
                if (empty($result)) {
184
                        fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
185
                        fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
186
                        fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
187
                }
188
        } else {
189
                fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
190
                fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
191
                fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
192
        }
193

    
194
        /* invalidate interface cache */
195
        get_interface_arr(true);
196

    
197
        if (!stristr($qinqif, "vlan"))
198
                mwexec("/sbin/ifconfig {$qinqif} promisc\n");
199

    
200
        $macaddr = get_interface_mac($qinqif);
201
        if (!empty($vlan['members'])) {
202
                $members = explode(" ", $vlan['members']);
203
                foreach ($members as $qtag) {
204
                        $qinq = array();
205
                        $qinq['tag'] = $qtag;
206
                        $qinq['if'] = $vlanif;
207
                        interface_qinq2_configure($qinq, $fd, $macaddr);
208
                }
209
        }
210
        if ($exec == true) {
211
                fclose($fd);
212
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
213
        }
214

    
215
        interfaces_bring_up($qinqif);
216
        if (!empty($vlan['members'])) {
217
                $members = explode(" ", $vlan['members']);
218
                foreach ($members as $qif)
219
                        interfaces_bring_up("{$vlanif}_{$qif}");
220
        }
221

    
222
        return $vlanif;
223
}
224

    
225
function interfaces_qinq_configure() {
226
	global $config, $g;
227
	if($g['booting'])
228
		echo "Configuring QinQ interfaces...";
229
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
230
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
231
			/* XXX: Maybe we should report any errors?! */
232
			interface_qinq_configure($qinq);
233
		}
234
	}
235
	if($g['booting'])
236
		echo "done.\n";
237
}
238

    
239
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
240
        global $config, $g;
241

    
242
        if (!is_array($qinq)) {
243
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
244
                return;
245
        }
246

    
247
        $if = $qinq['if'];
248
        $tag = $qinq['tag'];
249
        $vlanif = "{$if}_{$tag}";
250
        if(empty($if)) {
251
                log_error("interface_qinq_confgure called with if undefined.\n");
252
                return;
253
        }
254

    
255
        fwrite($fd, "shutdown {$if}h{$tag}:\n");
256
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
257
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
258
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
259
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
260
        fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
261

    
262
        /* invalidate interface cache */
263
        get_interface_arr(true);
264

    
265
        return $vlanif;
266
}
267

    
268
function interfaces_create_wireless_clones() {
269
	global $config;
270

    
271
	if($g['booting'])
272
		echo "Creating other wireless clone interfaces...";
273
	if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
274
		foreach ($config['wireless']['clone'] as $clone) {
275
			if(empty($clone['cloneif']))
276
				continue;
277
			if(does_interface_exist($clone['cloneif']))
278
				continue;
279
			/* XXX: Maybe we should report any errors?! */
280
			if(interface_wireless_clone($clone['cloneif'], $clone))
281
				if($g['booting'])
282
					echo " " . $clone['cloneif'];
283
		}
284
	}
285
	if($g['booting'])
286
		echo " done.\n";
287
}
288

    
289
function interfaces_bridge_configure() {
290
        global $config;
291

    
292
        $i = 0;
293
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
294
                foreach ($config['bridges']['bridged'] as $bridge) {
295
                        if(empty($bridge['bridgeif']))
296
                                $bridge['bridgeif'] = "bridge{$i}";
297
                        /* XXX: Maybe we should report any errors?! */
298
                        interface_bridge_configure($bridge);
299
                        $i++;
300
                }
301
        }
302
}
303

    
304
function interface_bridge_configure(&$bridge) {
305
	global $config, $g;
306

    
307
	if (!is_array($bridge))
308
	        return -1;
309

    
310
	if (empty($bridge['members'])) {
311
		log_error("No members found on {$bridge['bridgeif']}");
312
		return -1;
313
	}
314

    
315
	$members = explode(',', $bridge['members']);
316
	if (!count($members))
317
		return -1;
318

    
319
	$checklist = get_configured_interface_list();
320

    
321
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
322
		pfSense_interface_destroy($bridge['bridgeif']);
323
		pfSense_interface_create($bridge['bridgeif']);
324
		$bridgeif = $bridge['bridgeif'];
325
	} else
326
		$bridgeif = pfSense_interface_create("bridge");
327

    
328
	/* Calculate smaller mtu and enforce it */
329
	$smallermtu = 0;
330
	foreach ($members as $member) {
331
		$realif = get_real_interface($member);
332
		$mtu = get_interface_mtu($realif);
333
		if ($smallermtu == 0 && !empty($mtu))
334
			$smallermtu = $mtu;
335
		else if (!empty($mtu) && $mtu < $smallermtu)
336
			$smallermtu = $mtu;
337
	}
338
	 
339
	/* Just in case anything is not working well */
340
	if ($smallermtu == 0)
341
		$smallermtu = 1500; 
342

    
343
	/* Add interfaces to bridge */
344
	foreach ($members as $member) {
345
		if (!array_key_exists($member, $checklist))
346
			continue;
347
		$realif1 = get_real_interface($member);
348
		$realif =  escapeshellarg($realif1);
349
		/* make sure the parent interface is up */
350
		pfSense_interface_mtu($realif, $smallermtu);
351
		if(!$realif) 
352
			log_error("realif not defined in interfaces bridge - up");
353
		interfaces_bring_up($realif1);
354
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
355
	}
356

    
357
	if (isset($bridge['enablestp'])) {
358
		/* Choose spanning tree proto */
359
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
360
		
361
		if (!empty($bridge['stp'])) {
362
			$stpifs = explode(',', $bridge['stp']);
363
			foreach ($stpifs as $stpif) {
364
				$realif = get_real_interface($stpif);
365
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
366
			}
367
		}
368
		if (!empty($bridge['maxage']))
369
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
370
		if (!empty($brige['fwdelay']))
371
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
372
		if (!empty($brige['hellotime']))
373
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
374
		if (!empty($brige['priority']))
375
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
376
		if (!empty($brige['holdcount']))
377
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
378
		if (!empty($bridge['ifpriority'])) {
379
			$pconfig = explode(",", $bridge['ifpriority']);
380
			$ifpriority = array();
381
			foreach ($pconfig as $cfg) {
382
				$embcfg = explode(":", $cfg);
383
				foreach ($embcfg as $key => $value)
384
					$ifpriority[$key] = $value;
385
			}
386
			foreach ($ifpriority as $key => $value) {
387
				$realif = get_real_interface($key);
388
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
389
			}
390
		}
391
		if (!empty($bridge['ifpathcost'])) {
392
			$pconfig = explode(",", $bridges['ifpathcost']);
393
			$ifpathcost = array();
394
			foreach ($pconfig as $cfg) {
395
				$embcfg = explode(":", $cfg);
396
				foreach ($embcfg as $key => $value)
397
					$ifpathcost[$key] = $value;
398
			}
399
			foreach ($ifpathcost as $key => $value) {
400
                        	$realif = get_real_interface($key);
401
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
402
                	}
403
		}
404
	}
405

    
406
	if ($bridge['maxaddr'] <> "")
407
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
408
        if ($bridge['timeout'] <> "")
409
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
410
        if ($bridge['span'] <> "") {
411
		$realif = get_real_interface($bridge['span']);
412
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
413
	}
414
	if (!empty($bridge['edge'])) {
415
        	$edgeifs = explode(',', $bridge['edge']);
416
        	foreach ($edgeifs as $edgeif) {
417
			$realif = get_real_interface($edgeif);
418
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
419
        	}
420
	}
421
	if (!empty($bridge['autoedge'])) {
422
        	$edgeifs = explode(',', $bridge['autoedge']);
423
        	foreach ($edgeifs as $edgeif) {
424
                	$realif = get_real_interface($edgeif);
425
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
426
        	}
427
	}
428
	if (!empty($bridge['ptp'])) {
429
        	$ptpifs = explode(',', $bridge['ptp']);
430
        	foreach ($ptpifs as $ptpif) {
431
                	$realif = get_real_interface($ptpif);
432
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
433
        	}
434
	}
435
	if (!empty($bridge['autoptp'])) {
436
        	$ptpifs = explode(',', $bridge['autoptp']);
437
        	foreach ($ptpifs as $ptpif) {
438
                	$realif = get_real_interface($ptpif);
439
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
440
        	}
441
	}
442
	if (!empty($bridge['static'])) {
443
        	$stickyifs = explode(',', $bridge['static']);
444
        	foreach ($stickyifs as $stickyif) {
445
                	$realif = get_real_interface($stickyif);
446
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
447
        	}
448
	}
449
	if (!empty($bridge['private'])) {
450
        	$privateifs = explode(',', $bridge['private']);
451
        	foreach ($privateifs as $privateif) {
452
                	$realif = get_real_interface($privateif);
453
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
454
        	}
455
	}
456

    
457
	if($bridgeif)
458
		interfaces_bring_up($bridgeif);	
459
	else 
460
		log_error("bridgeif not defined -- could not bring interface up");
461

    
462
	return $bridgeif;
463
}
464

    
465
function interface_bridge_add_member($bridgeif, $interface) {
466

    
467
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
468
		return;
469

    
470
	$mtu = get_interface_mtu($brigeif);
471
	$mtum = get_interface_mtu($interface);
472
	
473
	if ($mtu != $mtum)
474
		pfSense_interface_mtu($interface, $mtu);
475

    
476
	pfSense_get_interface_addresses($bridgeif);
477
	if (isset($options['encaps']['txcsum']))
478
		pfSense_interface_capabilities($interface, IFCAP_TXCSUM);
479
	else
480
		pfSense_interface_capabilities($interface, -IFCAP_TXCSUM);
481

    
482
	if (isset($options['encaps']['rxcsum']))
483
		pfSense_interface_capabilities($interface, IFCAP_RXCSUM);
484
	else
485
		pfSense_interface_capabilities($interface, -IFCAP_RXCSUM);
486

    
487
	interfaces_bring_up($interface);
488
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
489
}
490

    
491
function interfaces_lagg_configure() 
492
{
493
        global $config, $g;
494
		if($g['booting']) 
495
			echo "Configuring LAGG interfaces...";
496
        $i = 0;
497
		if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
498
			foreach ($config['laggs']['lagg'] as $lagg) {
499
				if(empty($lagg['laggif']))
500
					$lagg['laggif'] = "lagg{$i}";
501
				/* XXX: Maybe we should report any errors?! */
502
				interface_lagg_configure($lagg);
503
				$i++;
504
			}
505
		}
506
		if($g['booting']) 
507
			echo "done.\n";
508
}
509

    
510
function interface_lagg_configure(&$lagg) {
511
        global $config, $g;
512

    
513
        if (!is_array($lagg))
514
		return -1;
515

    
516
	$members = explode(',', $lagg['members']);
517
	if (!count($members))
518
		return -1;
519
	
520
	$checklist = get_interface_list();
521

    
522
	if ($g['booting'] || !(empty($lagg['laggif']))) {
523
		pfSense_interface_destroy($lagg['laggif']);
524
		pfSense_interface_create($lagg['laggif']);
525
                $laggif = $lagg['laggif'];
526
        } else
527
		$laggif = pfSense_interface_create("lagg");
528

    
529
	/* Calculate smaller mtu and enforce it */
530
        $smallermtu = 0;
531
        foreach ($members as $member) {
532
                $mtu = get_interface_mtu($member);
533
		if ($smallermtu == 0 && !empty($mtu))
534
			$smallermtu = $mtu;
535
                else if (!empty($mtu) && $mtu < $smallermtu)
536
                        $smallermtu = $mtu;
537
        }
538

    
539
	/* Just in case anything is not working well */
540
        if ($smallermtu == 0)
541
                $smallermtu = 1500;
542

    
543
	foreach ($members as $member) {
544
		if (!array_key_exists($member, $checklist))
545
			continue;
546
		/* make sure the parent interface is up */
547
		pfSense_interface_mtu($member, $smallermtu);
548
		interfaces_bring_up($member);
549
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
550
	}
551
	
552
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
553

    
554
	interfaces_bring_up($laggif);
555

    
556
	return $laggif;
557
}
558

    
559
function interfaces_gre_configure() {
560
        global $config;
561

    
562
        $i = 0;
563
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
564
                foreach ($config['gres']['gre'] as $gre) {
565
                        if(empty($gre['greif']))
566
                                $gre['greif'] = "gre{$i}";
567
                        /* XXX: Maybe we should report any errors?! */
568
                        interface_gre_configure($gre);
569
                        $i++;
570
                }
571
        }
572
}
573

    
574
function interface_gre_configure(&$gre) {
575
        global $config, $g;
576

    
577
	if (!is_array($gre))
578
		return -1;
579

    
580
	$realif = get_real_interface($gre['if']);
581
	$realifip = get_interface_ip($gre['if']);
582

    
583
	/* make sure the parent interface is up */
584
	interfaces_bring_up($realif);
585

    
586
	if ($g['booting'] || !(empty($gre['greif']))) {
587
		pfSense_interface_destroy($gre['greif']);
588
		pfSense_interface_create($gre['greif']);
589
		$greif = $gre['greif'];
590
	} else
591
		$greif = pfSense_interface_create("gre");
592

    
593
	/* Do not change the order here for more see gre(4) NOTES section. */
594
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
595
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
596
	if (isset($gre['link0']) && $gre['link0'])
597
		pfSense_interface_flags($greif, IFF_LINK0);
598
	if (isset($gre['link1']) && $gre['link1'])
599
		pfSense_interface_flags($greif, IFF_LINK1);
600
	if (isset($gre['link2']) && $gre['link2'])
601
		pfSense_interface_flags($greif, IFF_LINK2);
602

    
603
	if($greif)
604
		interfaces_bring_up($greif);
605
	else 
606
		log_error("Could not bring greif up -- variable not defined.");
607

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

    
612
	return $greif;
613
}
614

    
615
function interfaces_gif_configure() {
616
	global $config;
617
	$i = 0;
618
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
619
		foreach ($config['gifs']['gif'] as $gif) {
620
			if(empty($gif['gifif']))
621
				$gre['gifif'] = "gif{$i}";
622
			/* XXX: Maybe we should report any errors?! */
623
			interface_gif_configure($gif);
624
			$i++;
625
		}
626
	}
627
}
628

    
629
function interface_gif_configure(&$gif) {
630
	global $config, $g;
631

    
632
	if (!is_array($gif))
633
		return -1;
634

    
635
	$realif = get_real_interface($gif['if']);
636
	$realifip = get_interface_ip($gif['if']);
637

    
638
	/* make sure the parent interface is up */
639
	if($realif)
640
		interfaces_bring_up($realif);
641
	else 
642
		log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
643

    
644
	if ($g['booting'] || !(empty($gif['gifif']))) {
645
		pfSense_interface_destroy($gif['gifif']);
646
		pfSense_interface_create($gif['gifif']);
647
		$gifif = $gif['gifif'];
648
	} else
649
		$gifif = pfSense_interface_create("gif");
650

    
651
	/* Do not change the order here for more see gif(4) NOTES section. */
652
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
653
	mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
654
	if (isset($gif['link0']) && $gif['link0'])
655
		pfSense_interface_flags($gifif, IFF_LINK0);
656
	if (isset($gif['link1']) && $gif['link1'])
657
		pfSense_interface_flags($gifif, IFF_LINK1);
658
	if($gifif)
659
		interfaces_bring_up($gifif);
660
	else
661
		log_error("could not bring gifif up -- variable not defined");
662

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

    
667
	return $gifif;
668
}
669

    
670
function interfaces_configure() {
671
	global $config, $g;
672

    
673
	/* Set up our loopback interface */
674
	interfaces_loopback_configure();
675

    
676
	/* set up LAGG virtual interfaces */
677
	interfaces_lagg_configure();
678

    
679
	/* set up VLAN virtual interfaces */
680
	interfaces_vlan_configure();
681

    
682
	interfaces_qinq_configure();
683

    
684
	$iflist = get_configured_interface_with_descr();
685
	$delayed_list = array();
686
	$bridge_list = array();
687
	
688
	/* This is needed to speedup interfaces on bootup. */
689
	$reload = false;
690
	if ($g['booting'])
691
		$reload = true;
692

    
693
	foreach($iflist as $if => $ifname) {
694
		$realif = $config['interfaces'][$if]['if'];
695
		if (strstr($realif, "bridge")) 
696
			$bridge_list[$if] = $ifname;
697
		else if (strstr($realif, "gre"))
698
			$delayed_list[$if] = $ifname;
699
		else if (strstr($realif, "gif"))
700
			$delayed_list[$if] = $ifname;
701
		else {
702
			if ($g['booting'])
703
				echo "Configuring {$ifname} interface...";
704
			if($g['debug'])
705
				log_error("Configuring {$ifname}");
706
			interface_configure($if, $reload);
707
			if ($g['booting']) 
708
				echo "done.\n";
709
		}
710
	}
711

    
712
	/* create the unconfigured wireless clones */
713
	interfaces_create_wireless_clones();
714

    
715
	/* set up GRE virtual interfaces */
716
	interfaces_gre_configure();
717

    
718
	/* set up GIF virtual interfaces */
719
	interfaces_gif_configure();
720
	
721
	foreach ($delayed_list as $if => $ifname) {
722
		if ($g['booting'])
723
			echo "Configuring {$ifname} interface...";
724
        	if ($g['debug'])
725
        		log_error("Configuring {$ifname}");
726

    
727
		interface_configure($if, $reload);
728

    
729
		if ($g['booting'])
730
			echo "done.\n";
731
	}
732

    
733
	/* set up BRIDGe virtual interfaces */
734
	interfaces_bridge_configure();
735

    
736
	foreach ($bridge_list as $if => $ifname) {
737
		if ($g['booting'])
738
			echo "Configuring {$ifname} interface...";
739
		if($g['debug'])
740
			log_error("Configuring {$ifname}");
741

    
742
		interface_configure($if, $reload);
743

    
744
		if ($g['booting'])
745
			echo "done.\n";
746
	}
747

    
748
	/* bring up vip interfaces */
749
	interfaces_vips_configure();
750

    
751
	/* configure interface groups */
752
	interfaces_group_setup();
753

    
754
	if (!$g['booting']) {
755
		/* reconfigure static routes (kernel may have deleted them) */
756
		system_routing_configure();
757

    
758
		/* reload IPsec tunnels */
759
		vpn_ipsec_configure();
760

    
761
		/* reload dhcpd (interface enabled/disabled status may have changed) */
762
		services_dhcpd_configure();
763

    
764
		/* restart dnsmasq */
765
		services_dnsmasq_configure();
766

    
767
		/* reload captive portal */
768
		captiveportal_init_rules();
769

    
770
		/* set the reload filter dity flag */
771
		filter_configure();
772
	}
773

    
774
	return 0;
775
}
776

    
777
function interface_reconfigure($interface = "wan") {
778
	interface_bring_down($interface);
779
	interface_configure($interface, true);
780
}
781

    
782
function interface_vip_bring_down(&$vip) {
783
	global $g;
784

    
785
	switch ($vip['mode']) {
786
	case "proxyarp":
787
		$vipif = get_real_interface($vip['interface']);
788
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
789
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
790
		break;
791
	case "ipalias":
792
		$vipif = get_real_interface($vip['interface']);
793
		if(does_interface_exist($vipif))
794
			pfSense_interface_deladdress($vipif, $vip['subnet']);
795
		break;
796
	case "carp":
797
		$vipif = "vip" . $vip['vhid'];
798
		if(does_interface_exist($vipif)) 
799
			pfSense_interface_destroy($vipif);
800
		break;
801
	case "carpdev-dhcp":
802
		$vipif = "vip" . $vip['vhid'];
803
		if(does_interface_exist($vipif)) 
804
			pfSense_interface_destroy($vipif);
805
		break;
806
	}
807
}
808

    
809
function interface_bring_down($interface = "wan", $destroy = false) {
810
	global $config, $g;
811

    
812
	if (!isset($config['interfaces'][$interface]))
813
		return; 
814

    
815
	$ifcfg = $config['interfaces'][$interface];
816

    
817
	$realif = get_real_interface($interface);
818

    
819
	switch ($ifcfg['ipaddr']) {
820
	case "ppp":
821
	case "pppoe":
822
	case "pptp":
823
	case "l2tp":
824
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
825
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
826
				if ($realif == $ppp['if']) {
827
					killbypid("{$g['varrun_path']}/{$ifcfg['ipaddr']}_{$interface}.pid");
828
					sleep(2);
829
					unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
830
					if (isset($ppp['ondemand']) && !$destroy) {
831
						interface_configure("wan");
832
					}
833
					break;
834
				}
835
			}
836
		}
837
		break;
838
	case "carpdev-dhcp":
839
		/* 
840
		 * NB: When carpdev gets enabled it would be better to be handled as all
841
		 *	   other interfaces! 
842
		 */
843
	case "dhcp":
844
		$pid = find_dhclient_process($realif);
845
		if($pid)
846
			mwexec("kill {$pid}");
847
		sleep(1);
848
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
849
		if(does_interface_exist("$realif")) {
850
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
851
			pfSense_interface_flags($realif, -IFF_UP);
852
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
853
		}
854
		break;
855
	default:
856
		if(does_interface_exist("$realif")) {
857
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
858
			pfSense_interface_flags($realif, -IFF_UP);
859
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
860
		}
861
		break;
862
	}
863

    
864
	/* remove interface up file if it exists */
865
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
866
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
867
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
868
	
869
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
870
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
871
	if (is_array($ifcfg['wireless'])) {
872
		mwexec(kill_hostapd($realif));
873
		mwexec(kill_wpasupplicant($realif));
874
	}
875

    
876
	if ($destroy == true) {
877
		if (preg_match("/^vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
878
			pfSense_interface_destroy($realif);
879
	}	
880

    
881
	return;
882
}
883

    
884
function interfaces_ptpid_used($ptpid) {
885
	global $config;
886

    
887
	if (is_array($config['ppps']['ppp']))
888
		foreach ($config['ppps']['ppp'] as & $settings)
889
			if ($ptpid == $settings['ptpid'])
890
				return true;
891

    
892
	return false;
893
}
894

    
895
function interfaces_ptpid_next() {
896

    
897
	$ptpid = 0;
898
	while(interfaces_ptpid_used($ptpid))
899
		$ptpid++;
900

    
901
	return $ptpid;
902
}
903

    
904
function getMPDCRONSettings($pppif_) {
905
	global $config;
906
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
907
	if (is_array($config['cron']['item'])) {
908
		for ($i = 0; $i < count($config['cron']['item']); $i++) {
909
			$item = $config['cron']['item'][$i];
910
			if (strpos($item['command'], $cron_cmd_file.$pppif_) !== false) {
911
				return array("ID" => $i, "ITEM" => $item);
912
			}
913
		}
914
	}
915
	return NULL;
916
}
917

    
918
function handle_pppoe_reset($post_array) {
919
	global $config, $g;
920

    
921
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
922

    
923
	$pppif = $post_array['type'].$post_array['ptpid'];
924
	if (!is_array($config['cron']['item'])) 
925
		$config['cron']['item'] = array(); 
926
	$itemhash = getMPDCRONSettings($pppif);
927
	$item = $itemhash['ITEM'];
928
	
929
	// reset cron items if necessary and return
930
	if (empty($post_array['pppoe-reset-type'])) {
931
		if (isset($item))
932
			unset($config['cron']['item'][$itemhash['ID']]);
933
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
934
		return;
935
	}
936

    
937
	if (empty($item)) 
938
		$item = array();
939
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
940
		$item['minute'] = $post_array['pppoe_resetminute'];
941
		$item['hour'] = $post_array['pppoe_resethour'];
942
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
943
			$date = explode("/", $post_array['pppoe_resetdate']);
944
			$item['mday'] = $date[1];
945
			$item['month'] = $date[0];
946
		} else {
947
			$item['mday'] = "*";
948
			$item['month'] = "*";
949
		}
950
		$item['wday'] = "*";
951
		$item['who'] = "root";
952
		$item['command'] = $cron_cmd_file.$pppif;
953
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
954
		switch ($post_array['pppoe_pr_preset_val']) {
955
			case "monthly":
956
				$item['minute'] = "0";
957
				$item['hour'] = "0";
958
				$item['mday'] = "1";
959
				$item['month'] = "*";
960
				$item['wday'] = "*";
961
				$item['who'] = "root";
962
				$item['command'] = $cron_cmd_file.$pppif;
963
				break;
964
	        case "weekly":
965
				$item['minute'] = "0";
966
				$item['hour'] = "0";
967
				$item['mday'] = "*";
968
				$item['month'] = "*";
969
				$item['wday'] = "0";
970
				$item['who'] = "root";
971
				$item['command'] = $cron_cmd_file.$pppif;
972
				break;
973
			case "daily":
974
				$item['minute'] = "0";
975
				$item['hour'] = "0";
976
				$item['mday'] = "*";
977
				$item['month'] = "*";
978
				$item['wday'] = "*";
979
				$item['who'] = "root";
980
				$item['command'] = $cron_cmd_file.$pppif;
981
				break;
982
			case "hourly":
983
				$item['minute'] = "0";
984
				$item['hour'] = "*";
985
				$item['mday'] = "*";
986
				$item['month'] = "*";
987
				$item['wday'] = "*";
988
				$item['who'] = "root";
989
				$item['command'] = $cron_cmd_file.$pppif;
990
				break;
991
		} // end switch
992
	} else {
993
		/* test whether a cron item exists and unset() it if necessary */
994
		$itemhash = getMPDCRONSettings($pppif);
995
		$item = $itemhash['ITEM'];
996
		if (isset($item))
997
			unset($config['cron']['item'][$itemhash['ID']]); 
998
	}// end if
999
	if (isset($itemhash['ID'])) 
1000
		$config['cron']['item'][$itemhash['ID']] = $item;
1001
	else 
1002
		$config['cron']['item'][] = $item;
1003
}
1004

    
1005
/*	This function can configure PPPoE, MLPPP (PPPoE), PPTP.
1006
*	It writes the mpd config file to /var/etc every time the link is opened.
1007
*/
1008

    
1009
function interface_ppps_configure($interface) {
1010
	global $config, $g;
1011
	
1012
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1013
	if(!is_dir("/var/spool/lock")) {
1014
		exec("/bin/mkdir -p /var/spool/lock");
1015
		exec("/bin/chmod a+rw /var/spool/lock/.");
1016
	}
1017
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files	
1018
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1019
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1020
		
1021
	$ifcfg = &$config['interfaces'][$interface];
1022
	if (!isset($ifcfg['enable']))
1023
		return 0;
1024
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1025
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1026
			if ($ifcfg['if'] == $ppp['if'])
1027
				break;
1028
		}
1029
	}
1030
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1031
		log_error("Can't find PPP config for {$ifcfg['if']} in interface_ppps_configure().");
1032
		return 0;
1033
	}
1034
	$pppif = $ifcfg['if'];
1035
	if ($ppp['type'] == "ppp")
1036
		$type = "modem";
1037
	else
1038
		$type = $ppp['type'];
1039
	$upper_type = strtoupper($ppp['type']);	
1040
	
1041
	if($g['booting']) {
1042
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1043
		echo " configuring {$upper_type} on {$descr} interface...\n";
1044
		// Do not re-configure the interface if we are booting and it's already been started
1045
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1046
			return 0;
1047
	}
1048
	
1049
	$ports = explode(',',$ppp['ports']);
1050
	if ($type != "modem") {
1051
		foreach ($ports as $pid => $port)
1052
			$ports[$pid] = get_real_interface($port);
1053
	}
1054
	$localips = explode(',',$ppp['localip']);
1055
	$gateways = explode(',',$ppp['gateway']);
1056
	$subnets = explode(',',$ppp['subnet']);
1057
	
1058
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1059
	to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1060
	*/
1061
	foreach($ports as $pid => $port){
1062
		switch ($ppp['type']) {
1063
			case "pppoe": 
1064
				/* Bring the parent interface up */
1065
				interfaces_bring_up($port);
1066
				break;
1067
			case "pptp":
1068
			case "l2tp":
1069
				/* configure interface */
1070
				if(is_ipaddr($localips[$pid])){
1071
					// Manually configure interface IP/subnet
1072
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1073
					interfaces_bring_up($port);
1074
				} else if (empty($localips[$pid]))
1075
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1076
				
1077
				if(!is_ipaddr($localips[$pid])){
1078
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure.");
1079
					return 0;
1080
				}
1081
				/* XXX: This needs to go away soon! [It's commented out!] */
1082
				/* Configure the gateway (remote IP ) */
1083
				if (!$g['booting'] && !is_ipaddr($gateways[$pid]) && is_hostname($gateways[$pid])) {
1084
					/* XXX: Fix later 
1085
					$gateways[$pid] = gethostbyname($gateways[$pid]);
1086
					if(!is_ipaddr($gateways[$pid])) {
1087
						log_error("Could not get a valid Gateway IP from {$port} via DNS in interfaces_ppps_configure.");
1088
						return 0;
1089
					}
1090
					*/
1091
				}
1092
				if(!is_ipaddr($gateways[$pid])){
1093
					log_error("Could not get a PPTP/L2TP Remote IP address from {$dhcp_gateway} for {$gway} in interfaces_ppps_configure.");
1094
					return 0;
1095
				}
1096
				break;
1097
			case "ppp":
1098
				if (!file_exists("{$port}")) {
1099
					log_error("Device {$port} does not exist. PPP link cannot start without the modem device.");
1100
					return 0;
1101
				}
1102
				break;
1103
			default:
1104
				log_error("Unkown {$type} configured as ppp interface.");
1105
				break;
1106
		}
1107
	}
1108

    
1109
	/* generate mpd.conf */
1110
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1111
	if (!$fd) {
1112
		log_error("Error: cannot open mpd_{$interface}.conf in interface_ppps_configure().\n");
1113
		return 0;
1114
	}
1115
	
1116
	if (is_array($ports) && count($ports) > 1)
1117
		$multilink = "enable";
1118
	else
1119
		$multilink = "disable";
1120
	
1121
	if ($type == "modem"){
1122
		if (is_ipaddr($ppp['localip']))
1123
			$localip = $ppp['localip'];
1124
		else
1125
			$localip = '0.0.0.0';
1126

    
1127
		if (is_ipaddr($ppp['gateway']))
1128
			$gateway = $ppp['gateway'];
1129
		else
1130
			$gateway = "10.64.64.{$pppid}";
1131
		$ranges = "{$localip}/0 {$gateway}/0";
1132
		
1133
		if (empty($ppp['apnum']))	
1134
			$ppp['apnum'] = 1;
1135
	} else
1136
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1137

    
1138
	if (isset($ppp['ondemand'])) 
1139
		$ondemand = "enable";
1140
	else
1141
		$ondemand = "disable";
1142
	if (!isset($ppp['idletimeout']))
1143
		$ppp['idletimeout'] = 0;
1144

    
1145
	if (empty($ppp['username']) && $type == "modem"){
1146
		$ppp['username'] = "user";
1147
		$ppp['password'] = "none";
1148
	}
1149
	if (empty($ppp['password']) && $type == "modem")
1150
		$passwd = "none";
1151
	else
1152
		$passwd = base64_decode($ppp['password']);
1153

    
1154
	$bandwidths = explode(',',$ppp['bandwidth']);
1155
	$mtus = explode(',',$ppp['mtu']);
1156
	$mrus = explode(',',$ppp['mru']);
1157

    
1158
	if (isset($ppp['mrru']))
1159
		$mrrus = explode(',',$ppp['mrru']);
1160

    
1161
	// Construct the mpd.conf file
1162
	$mpdconf = <<<EOD
1163
startup:
1164
	# configure the console
1165
	set console close
1166
	# configure the web server
1167
	set web close
1168

    
1169
default:
1170
{$ppp['type']}client:
1171
	create bundle static {$interface}
1172
	set iface name {$pppif}
1173

    
1174
EOD;
1175
	$setdefaultgw = false;
1176
	$founddefaultgw = false;
1177
	if (is_array($config['gateways']['gateway_item'])) {
1178
		foreach($config['gateways']['gateway_item'] as $gateway) {
1179
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1180
				$setdefaultgw = true;
1181
				break;
1182
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1183
				$founddefaultgw = true;
1184
				break;
1185
			}
1186
		}
1187
	}
1188
	
1189
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1190
		$setdefaultgw = true;
1191
		$mpdconf .= <<<EOD
1192
	set iface route default
1193

    
1194
EOD;
1195
	}
1196
	$mpdconf .= <<<EOD
1197
	set iface {$ondemand} on-demand
1198
	set iface idle {$ppp['idletimeout']}
1199

    
1200
EOD;
1201

    
1202
	if (isset($ppp['ondemand']))
1203
		$mpdconf .= <<<EOD
1204
	set iface addrs 10.10.1.1 10.10.1.2
1205

    
1206
EOD;
1207
	
1208
	if (isset($ppp['tcpmssfix']))
1209
		$tcpmss = "disable";
1210
	else
1211
		$tcpmss = "enable";
1212
		$mpdconf .= <<<EOD
1213
	set iface {$tcpmss} tcpmssfix
1214

    
1215
EOD;
1216

    
1217
	$mpdconf .= <<<EOD
1218
	set iface up-script /usr/local/sbin/ppp-linkup
1219
	set iface down-script /usr/local/sbin/ppp-linkdown
1220
	set ipcp ranges {$ranges}
1221

    
1222
EOD;
1223
	if (isset($ppp['vjcomp']))
1224
		$mpdconf .= <<<EOD
1225
	set ipcp no vjcomp
1226

    
1227
EOD;
1228

    
1229
	if (isset($config['system']['dnsallowoverride']))
1230
		$mpdconf .= <<<EOD
1231
	set ipcp enable req-pri-dns
1232
	set ipcp enable req-sec-dns
1233

    
1234
EOD;
1235
	if (!isset($ppp['verbose_log']))
1236
		$mpdconf .= <<<EOD
1237
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1238

    
1239
EOD;
1240
	foreach($ports as $pid => $port){
1241
		$port = get_real_interface($port);
1242
		$mpdconf .= <<<EOD
1243

    
1244
	create link static {$interface}_link{$pid} {$type}
1245
	set link action bundle {$interface}
1246
	set link {$multilink} multilink
1247
	set link keep-alive 10 60
1248
	set link max-redial 0
1249

    
1250
EOD;
1251
		if (isset($ppp['shortseq']))
1252
			$mpdconf .= <<<EOD
1253
	set link no shortseq
1254

    
1255
EOD;
1256

    
1257
		if (isset($ppp['acfcomp']))
1258
			$mpdconf .= <<<EOD
1259
	set link no acfcomp
1260

    
1261
EOD;
1262

    
1263
		if (isset($ppp['protocomp']))
1264
			$mpdconf .= <<<EOD
1265
	set link no protocomp
1266

    
1267
EOD;
1268

    
1269
		$mpdconf .= <<<EOD
1270
	set link disable chap pap
1271
	set link accept chap pap eap
1272
	set link disable incoming
1273

    
1274
EOD;
1275

    
1276

    
1277
		if (!empty($bandwidths[$pid]))
1278
			$mpdconf .= <<<EOD
1279
	set link bandwidth {$bandwidths[$pid]}
1280

    
1281
EOD;
1282

    
1283
		if (empty($mtus[$pid]))
1284
			$mtus[$pid] = "1492";
1285
			$mpdconf .= <<<EOD
1286
	set link mtu {$mtus[$pid]}
1287

    
1288
EOD;
1289

    
1290
		if (!empty($mrus[$pid]))
1291
			$mpdconf .= <<<EOD
1292
	set link mru {$mrus[$pid]}
1293

    
1294
EOD;
1295

    
1296
		$mpdconf .= <<<EOD
1297
	set auth authname "{$ppp['username']}"
1298
	set auth password {$passwd}
1299

    
1300
EOD;
1301
		if ($type == "modem") {
1302
			$mpdconf .= <<<EOD
1303
	set modem device {$ppp['ports']}
1304
	set modem script DialPeer
1305
	set modem idle-script Ringback
1306
	set modem watch -cd
1307
	set modem var \$DialPrefix "DT"
1308
	set modem var \$Telephone "{$ppp['phone']}"
1309

    
1310
EOD;
1311
		}
1312
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1313
			$mpdconf .= <<<EOD
1314
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1315

    
1316
EOD;
1317
		}
1318
		if (isset($ppp['initstr']) && $type == "modem") {
1319
			$initstr = base64_decode($ppp['initstr']);
1320
			$mpdconf .= <<<EOD
1321
	set modem var \$InitString "{$initstr}"
1322

    
1323
EOD;
1324
		}
1325
		if (isset($ppp['simpin']) && $type == "modem") {
1326
			$mpdconf .= <<<EOD
1327
	set modem var \$SimPin "{$ppp['simpin']}"
1328
	set modem var \$PinWait "{$ppp['pin-wait']}"
1329

    
1330
EOD;
1331
		}
1332
		if (isset($ppp['apn']) && $type == "modem") {
1333
			$mpdconf .= <<<EOD
1334
	set modem var \$APN "{$ppp['apn']}"
1335
	set modem var \$APNum "{$ppp['apnum']}"
1336

    
1337
EOD;
1338
		}
1339
		if (isset($ppp['provider']) && $type == "pppoe") {
1340
			$mpdconf .= <<<EOD
1341
	set pppoe service "{$ppp['provider']}"
1342

    
1343
EOD;
1344
		}
1345
		if ($type == "pppoe")
1346
			$mpdconf .= <<<EOD
1347
	set pppoe iface {$port}
1348

    
1349
EOD;
1350

    
1351
		if ($type == "pptp" || $type == "l2tp") {
1352
			$mpdconf .= <<<EOD
1353
	set pptp self {$localips[$pid]}
1354
	set pptp peer {$gateways[$pid]}
1355
	set pptp disable windowing
1356

    
1357
EOD;
1358
		}
1359
		
1360
		$mpdconf .= "\topen\r\n";
1361
	} //end foreach($port)
1362

    
1363
	// Write out mpd_ppp.conf
1364
	fwrite($fd, $mpdconf);
1365
	fclose($fd);
1366

    
1367
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1368
	if (isset($ppp['uptime'])) {
1369
		if (!file_exists("/conf/{$pppif}.log")) {
1370
			conf_mount_rw();
1371
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1372
			conf_mount_ro();
1373
		}
1374
	} else {
1375
		if (file_exists("/conf/{$pppif}.log")) {
1376
			conf_mount_rw();
1377
			mwexec("rm -f /conf/{$pppif}.log");
1378
			conf_mount_ro();
1379
		}
1380
	}
1381
		
1382
	/* fire up mpd */
1383
	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");
1384

    
1385
	// Check for PPPoE periodic reset request 
1386
	if ($type == "pppoe") {
1387
		if (isset($ppp['pppoe-reset-type']))
1388
			setup_pppoe_reset_file($ppp['if'], $interface);
1389
		else
1390
			setup_pppoe_reset_file($ppp['if']);
1391
	}
1392

    
1393
	return 1;
1394
}
1395

    
1396
function interfaces_carp_setup() {
1397
	global $g, $config;
1398

    
1399
	$balanacing = "";
1400
	$pfsyncinterface = "";
1401
	$pfsyncenabled = "";
1402
	if(isset($config['system']['developerspew'])) {
1403
		$mt = microtime();
1404
		echo "interfaces_carp_setup() being called $mt\n";
1405
	}
1406

    
1407
	// Prepare CmdCHAIN that will be used to execute commands.
1408
	$cmdchain = new CmdCHAIN();	
1409

    
1410
	if ($g['booting']) {
1411
		echo "Configuring CARP settings...";
1412
		mute_kernel_msgs();
1413
	}
1414

    
1415
	/* suck in configuration items */
1416
	if($config['installedpackages']['carpsettings']) {
1417
		if($config['installedpackages']['carpsettings']['config']) {
1418
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1419
				$pfsyncenabled = $carp['pfsyncenabled'];
1420
				$balanacing = $carp['balancing'];
1421
				$pfsyncinterface = $carp['pfsyncinterface'];
1422
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1423
			}
1424
		}
1425
	} else {
1426
		unset($pfsyncinterface);
1427
		unset($balanacing);
1428
		unset($pfsyncenabled);
1429
	}
1430

    
1431
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1432
	if($balanacing) {
1433
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1434
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1435
	} else
1436
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1437

    
1438
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=2", true);
1439
	if (!empty($pfsyncinterface))
1440
		$carp_sync_int = get_real_interface($pfsyncinterface);
1441

    
1442
	if($g['booting']) {
1443
		/*    install rules to alllow pfsync to sync up during boot
1444
		 *    carp interfaces will remain down until the bootup sequence finishes
1445
		 */
1446
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1447
		if ($fd) {
1448
			fwrite($fd, "pass quick proto carp all keep state\n");
1449
			fwrite($fd, "pass quick proto pfsync all\n");
1450
			fwrite($fd, "pass out quick from any to any keep state\n");
1451
			fclose($fd);
1452
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1453
		} else
1454
			log_error("Could not create rules.boot file!");
1455
	}
1456

    
1457
	/* setup pfsync interface */
1458
	if($carp_sync_int and $pfsyncenabled) {
1459
		if (is_ipaddr($pfsyncpeerip))
1460
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1461
		else
1462
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1463
	} else
1464
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1465

    
1466
	if($config['virtualip']['vip'])
1467
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1468
	else
1469
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1470
	
1471
	if($g['debug'])
1472
		$cmdchain->setdebug(); // optional for verbose logging
1473

    
1474
	$cmdchain->execute();
1475
	$cmdchain->clear();
1476

    
1477
	if ($g['booting']) {
1478
		unmute_kernel_msgs();
1479
		echo "done.\n";
1480
	}
1481
}
1482

    
1483
function interface_proxyarp_configure($interface = "") {
1484
	global $config, $g;
1485
	if(isset($config['system']['developerspew'])) {
1486
		$mt = microtime();
1487
		echo "interface_proxyarp_configure() being called $mt\n";
1488
	}
1489

    
1490
	/* kill any running choparp */
1491
	if (empty($interface))
1492
		killbyname("choparp");
1493

    
1494
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1495
		$paa = array();
1496

    
1497
		/* group by interface */
1498
		foreach ($config['virtualip']['vip'] as $vipent) {
1499
			if ($vipent['mode'] === "proxyarp") {
1500
				if ($vipent['interface'])
1501
					$proxyif = $vipent['interface'];
1502
				else
1503
					$proxyif = "wan";
1504

    
1505
				if (!is_array($paa[$if]))
1506
					$paa[$proxyif] = array();
1507

    
1508
				$paa[$proxyif][] = $vipent;
1509
			}
1510
		}
1511
	}
1512

    
1513
	if (!empty($interface)) {
1514
		if (is_array($paa[$interface])) {
1515
			$paaifip = get_interface_ip($interface);
1516
                        if (!is_ipaddr($paaifip))
1517
                                return;
1518
                        $args = get_real_interface($interface) . " auto";
1519
                        foreach ($paa[$interface] as $paent) {
1520
                                if (isset($paent['subnet']))
1521
                                        $args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1522
                                else if (isset($paent['range']))
1523
                                        $args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1524
                        }
1525
                        mwexec_bg("/usr/local/sbin/choparp " . $args);	
1526
		}
1527
	} else if (count($paa)) {
1528
		foreach ($paa as $paif => $paents) {
1529
			$paaifip = get_interface_ip($paif);
1530
			if (!(is_ipaddr($paaifip)))
1531
				continue;
1532
			$args = get_real_interface($paif) . " auto";
1533
			foreach ($paents as $paent) {
1534
				if (isset($paent['subnet']))
1535
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1536
				else if (isset($paent['range']))
1537
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1538
			}
1539
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1540
		}
1541
	}
1542
}
1543

    
1544
function interfaces_vips_configure($interface = "") {
1545
	global $g, $config;
1546
	if(isset($config['system']['developerspew'])) {
1547
		$mt = microtime();
1548
		echo "interfaces_vips_configure() being called $mt\n";
1549
	}
1550
	$paa = array();
1551
	if(is_array($config['virtualip']['vip'])) {
1552
		$carp_setuped = false;
1553
		$anyproxyarp = false;
1554
		foreach ($config['virtualip']['vip'] as $vip) {
1555
			switch ($vip['mode']) {
1556
			case "proxyarp":
1557
				/* nothing it is handled on interface_proxyarp_configure() */
1558
				if ($interface <> "" && $vip['interface'] <> $interface)
1559
					continue;
1560
				$anyproxyarp = true;
1561
				break;
1562
			case "ipalias":
1563
				if ($interface <> "" && $vip['interface'] <> $interface)
1564
					continue;
1565
				interface_ipalias_configure(&$vip);
1566
				break;
1567
			case "carp":
1568
				if ($interface <> "" && $vip['interface'] <> $interface)
1569
					continue;
1570
				if ($carp_setuped == false) {
1571
					interfaces_carp_setup();
1572
					$carp_setuped = true;
1573
				}
1574
				interface_carp_configure($vip);
1575
				break;
1576
			case "carpdev-dhcp":
1577
				if ($interface <> "" && $vip['interface'] <> $interface)
1578
					continue;
1579
				interface_carpdev_configure($vip);
1580
				break;
1581
			}
1582
		}
1583
		
1584
		if ($anyproxyarp == true)
1585
			interface_proxyarp_configure();
1586
	}
1587
}
1588

    
1589
function interface_ipalias_configure(&$vip) {
1590

    
1591
	if ($vip['mode'] == "ipalias") {
1592
		$if = get_real_interface($vip['interface']);
1593
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1594
	}
1595
}
1596

    
1597
function interface_reload_carps($cif) {
1598
	global $config;
1599

    
1600
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1601
	if (empty($carpifs))
1602
		return;
1603

    
1604
	$carps = explode(" ", $carpifs);
1605
	if(is_array($config['virtualip']['vip'])) {
1606
		$viparr = &$config['virtualip']['vip'];
1607
		foreach ($viparr as $vip) {
1608
			if (in_array($vip['carpif'], $carps)) {
1609
				switch ($vip['mode']) {
1610
				case "carp":
1611
					interface_vip_bring_down($vip);
1612
					sleep(1);
1613
					interface_carp_configure($vip);
1614
					break;
1615
				case "carpdev-dhcp":
1616
					interface_vip_bring_down($vip);
1617
					sleep(1);
1618
					interface_carpdev_configure($vip);
1619
					break;
1620
				case "ipalias":
1621
					interface_vip_bring_down($vip);
1622
					sleep(1);
1623
					interface_ipalias_configure($vip);
1624
					break;
1625
				}
1626
			}
1627
		}
1628
	}
1629
}
1630

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

    
1638
	if ($vip['mode'] != "carp")
1639
		return;
1640

    
1641
	$vip_password = $vip['password'];
1642
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1643
	if ($vip['password'] != "")
1644
		$password = " pass {$vip_password}";
1645

    
1646
	// set the vip interface to the vhid
1647
	$vipif = "vip{$vip['vhid']}";
1648

    
1649
	$interface = interface_translate_type_to_real($vip['interface']);
1650
	/*
1651
	 * ensure the interface containing the VIP really exists
1652
 	 * prevents a panic if the interface is missing or invalid
1653
	 */
1654
	$realif = get_real_interface($vip['interface']);
1655
	if (!does_interface_exist($realif)) {
1656
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1657
		return;
1658
	}
1659

    
1660
	/* Ensure CARP IP really exists prior to loading up. */
1661
	$ww_subnet_ip = find_interface_ip($realif);
1662
	$ww_subnet_bits = find_interface_subnet($realif);
1663
	if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits)) {
1664
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1665
		return;
1666
	}
1667

    
1668
	/* create the carp interface and setup */
1669
	if (does_interface_exist($vipif)) {
1670
		pfSense_interface_flags($vipif, -IFF_UP);
1671
	} else {
1672
		$carpif = pfSense_interface_create("carp");
1673
		pfSense_interface_rename($carpif, $vipif);
1674
		pfSense_ngctl_name("{$carpif}:", $vipif);
1675
	}
1676

    
1677
	/* invalidate interface cache */
1678
	get_interface_arr(true);
1679

    
1680
	$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
1681
	mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1682

    
1683
	interfaces_bring_up($vipif);
1684
	
1685
	return $vipif;
1686
}
1687

    
1688
function interface_carpdev_configure(&$vip) {
1689
	global $g;
1690

    
1691
	if ($vip['mode'] != "carpdev-dhcp")
1692
		return;
1693

    
1694
	$vip_password = $vip['password'];
1695
	$vip_password = str_replace(" ", "", $vip_password);
1696
	if($vip['password'] != "")
1697
		$password = " pass \"" . $vip_password . "\"";
1698

    
1699
	log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1700
	if (empty($vip['interface']))
1701
		return;
1702

    
1703
	$vipif = "vip" . $vip['vhid'];
1704
	$realif = interface_translate_type_to_real($vip['interface']);
1705
	interfaces_bring_up($realif);
1706
	/*
1707
	 * ensure the interface containing the VIP really exists
1708
	 * prevents a panic if the interface is missing or invalid
1709
	 */
1710
	if (!does_interface_exist($realif)) {
1711
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1712
		return;
1713
	}
1714

    
1715
	if (does_interface_exist($vipif)) {
1716
		interface_bring_down($vipif);
1717
	} else {
1718
		$carpdevif = exec("/sbin/ifconfig carp create");
1719
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1720
		pfSense_ngctl_name("{$carpdevif}:", $vipif);
1721
	}
1722

    
1723
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1724
	interfaces_bring_up($vipif);
1725

    
1726
	/*
1727
	 * XXX: BIG HACK but carpdev needs ip services active
1728
	 *      before even starting something as dhclient.
1729
	 *      I do not know if this is a feature or a bug
1730
	 *      but better than track it make it work ;) .
1731
	 */
1732
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1733
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1734

    
1735
	/* generate dhclient_wan.conf */
1736
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1737
	if ($fd) {
1738
		$dhclientconf = "";
1739

    
1740
		$dhclientconf .= <<<EOD
1741
interface "{$vipif}" {
1742
timeout 60;
1743
retry 1;
1744
select-timeout 0;
1745
initial-interval 1;
1746
script "/sbin/dhclient-script";
1747
}
1748

    
1749
EOD;
1750

    
1751
		fwrite($fd, $dhclientconf);
1752
		fclose($fd);
1753

    
1754
		/* fire up dhclient */
1755
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} > {$g['tmp_path']}/{$vipif}_output > {$g['tmp_path']}/{$vipif}_error_output", false);
1756
	} else {
1757
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1758
		mwexec("/sbin/dhclient -b {$vipif}");
1759
	}
1760

    
1761
	return $vipif;
1762
}
1763

    
1764
function interface_wireless_clone($realif, $wlcfg) {
1765
	global $config, $g;
1766
	/*   Check to see if interface has been cloned as of yet.  
1767
	 *   If it has not been cloned then go ahead and clone it.
1768
	 */
1769
	$needs_clone = false;
1770
	if(is_array($wlcfg['wireless']))
1771
		$wlcfg_mode = $wlcfg['wireless']['mode'];
1772
	else
1773
		$wlcfg_mode = $wlcfg['mode'];
1774
	switch($wlcfg_mode) {
1775
		 case "hostap":
1776
			$mode = "wlanmode hostap";
1777
			break;
1778
		 case "adhoc":
1779
			$mode = "wlanmode adhoc";
1780
			break;
1781
		 default:
1782
			$mode = "";
1783
			break;
1784
	}
1785
	$baseif = interface_get_wireless_base($wlcfg['if']);
1786
	if(does_interface_exist($realif)) {
1787
		exec("/sbin/ifconfig {$realif}", $output, $ret);
1788
		$ifconfig_str = implode($output);
1789
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
1790
			log_error("Interface {$realif} changed to hostap mode");
1791
			$needs_clone = true;
1792
		}
1793
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
1794
			log_error("Interface {$realif} changed to adhoc mode");
1795
			$needs_clone = true;
1796
		}
1797
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
1798
			log_error("Interface {$realif} changed to infrastructure mode");
1799
			$needs_clone = true;
1800
		}
1801
	} else {
1802
		$needs_clone = true;
1803
	}
1804

    
1805
	if($needs_clone == true) {
1806
		/* remove previous instance if it exists */
1807
		if(does_interface_exist($realif))
1808
			pfSense_interface_destroy($realif);
1809

    
1810
		log_error("Cloning new wireless interface {$realif}");
1811
		// Create the new wlan interface. FreeBSD returns the new interface name.
1812
		// example:  wlan2
1813
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1814
		if($ret <> 0) {
1815
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1816
			return false;
1817
		}
1818
		$newif = trim($out[0]);
1819
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1820
		pfSense_interface_rename($newif, $realif);
1821
		// FIXME: not sure what ngctl is for. Doesn't work.
1822
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1823
	}
1824
	return true;
1825
}
1826

    
1827
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1828
	global $config, $g;
1829

    
1830
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel', 'distance', 'regdomain', 'regcountry', 'reglocation');
1831

    
1832
	if(!is_interface_wireless($ifcfg['if']))
1833
		return;
1834

    
1835
	$baseif = interface_get_wireless_base($ifcfg['if']);
1836

    
1837
	// Sync shared settings for assigned clones
1838
	$iflist = get_configured_interface_list(false, true);
1839
	foreach ($iflist as $if) {
1840
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
1841
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
1842
				foreach ($shared_settings as $setting) {
1843
					if ($sync_changes) {
1844
						$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
1845
					} else {
1846
						$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
1847
					}
1848
				}
1849
				if (!$sync_changes)
1850
					break;
1851
			}
1852
		}
1853
	}
1854

    
1855
	// Read or write settings at shared area
1856
	if (isset($config['wireless']['interfaces'][$baseif])) {
1857
		foreach ($shared_settings as $setting) {
1858
			if ($sync_changes) {
1859
				$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
1860
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
1861
				$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
1862
			}
1863
		}
1864
	}
1865

    
1866
	// Sync the mode on the clone creation page with the configured mode on the interface
1867
	if (interface_is_wireless_clone($ifcfg['if'])) {
1868
		foreach ($config['wireless']['clone'] as &$clone) {
1869
			if ($clone['cloneif'] == $ifcfg['if']) {
1870
				if ($sync_changes) {
1871
					$clone['mode'] = $ifcfg['wireless']['mode'];
1872
				} else {
1873
					$ifcfg['wireless']['mode'] = $clone['mode'];
1874
				}
1875
				break;
1876
			}
1877
		}
1878
		unset($clone);
1879
	}
1880
}
1881

    
1882
function interface_wireless_configure($if, &$wl, &$wlcfg) {
1883
	global $config, $g;
1884

    
1885
	/*    open up a shell script that will be used to output the commands.
1886
	 *    since wireless is changing a lot, these series of commands are fragile
1887
     *    and will sometimes need to be verified by a operator by executing the command
1888
     *    and returning the output of the command to the developers for inspection.  please
1889
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1890
	 */
1891

    
1892
	// Remove script file
1893
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1894

    
1895
	// Clone wireless nic if needed.
1896
	interface_wireless_clone($if, $wl);
1897

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

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

    
1905
	/* set values for /path/program */
1906
	$hostapd = "/usr/sbin/hostapd";
1907
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1908
	$ifconfig = "/sbin/ifconfig";
1909
	$killall = "/usr/bin/killall";
1910

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

    
1913
	$wlcmd = array();
1914
	/* Make sure it's up */
1915
	$wlcmd[] = "up";
1916
	/* Set a/b/g standard */
1917
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
1918
	$wlcmd[] = "mode " . escapeshellarg($standard);
1919

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

    
1925
	/* Set ssid */
1926
	if($wlcfg['ssid'])
1927
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
1928

    
1929
	/* Set 802.11g protection mode */
1930
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
1931

    
1932
	/* set wireless channel value */
1933
	if(isset($wlcfg['channel'])) {
1934
		if($wlcfg['channel'] == "0") {
1935
			$wlcmd[] = "channel any";
1936
		} else {
1937
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
1938
		}
1939
	}
1940

    
1941
	/* set Distance value */
1942
	if($wlcfg['distance'])
1943
		$distance = escapeshellarg($wlcfg['distance']);
1944

    
1945
	/* Set wireless hostap mode */
1946
	if ($wlcfg['mode'] == "hostap") {
1947
		$wlcmd[] = "mediaopt hostap";
1948
	} else {
1949
		$wlcmd[] = "-mediaopt hostap";
1950
	}
1951

    
1952
	/* Set wireless adhoc mode */
1953
	if ($wlcfg['mode'] == "adhoc") {
1954
		$wlcmd[] = "mediaopt adhoc";
1955
	} else {
1956
		$wlcmd[] = "-mediaopt adhoc";
1957
	}
1958

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

    
1961
	/* handle hide ssid option */
1962
	if(isset($wlcfg['hidessid']['enable'])) {
1963
		$wlcmd[] = "hidessid";
1964
	} else {
1965
		$wlcmd[] = "-hidessid";
1966
	}
1967

    
1968
	/* handle pureg (802.11g) only option */
1969
	if(isset($wlcfg['pureg']['enable'])) {
1970
		$wlcmd[] = "mode 11g pureg";
1971
	} else {
1972
		$wlcmd[] = "-pureg";
1973
	}
1974

    
1975
	/* handle puren (802.11n) only option */
1976
	if(isset($wlcfg['puren']['enable'])) {
1977
		$wlcmd[] = "puren";
1978
	} else {
1979
		$wlcmd[] = "-puren";
1980
	}
1981

    
1982
	/* enable apbridge option */
1983
	if(isset($wlcfg['apbridge']['enable'])) {
1984
		$wlcmd[] = "apbridge";
1985
	} else {
1986
		$wlcmd[] = "-apbridge";
1987
	}
1988

    
1989
	/* handle turbo option */
1990
	if(isset($wlcfg['turbo']['enable'])) {
1991
		$wlcmd[] = "mediaopt turbo";
1992
	} else {
1993
		$wlcmd[] = "-mediaopt turbo";
1994
	}
1995

    
1996
	/* handle txpower setting */
1997
	/* if($wlcfg['txpower'] <> "")
1998
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
1999
	*/
2000
	/* handle wme option */
2001
	if(isset($wlcfg['wme']['enable'])) {
2002
		$wlcmd[] = "wme";
2003
	} else {
2004
		$wlcmd[] = "-wme";
2005
	}
2006

    
2007
	/* set up wep if enabled */
2008
	$wepset = "";
2009
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2010
		switch($wlcfg['wpa']['auth_algs']) {
2011
			case "1":
2012
				$wepset .= "authmode open wepmode on ";
2013
				break;
2014
			case "2":
2015
				$wepset .= "authmode shared wepmode on ";
2016
				break;
2017
			case "3":
2018
				$wepset .= "authmode mixed wepmode on ";
2019
		}
2020
		$i = 1;
2021
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2022
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2023
			if (isset($wepkey['txkey'])) {
2024
				$wlcmd[] = "weptxkey {$i} ";
2025
			}
2026
			$i++;
2027
		}
2028
		$wlcmd[] = $wepset;
2029
	} else {
2030
		$wlcmd[] = "authmode open wepmode off ";
2031
	}
2032

    
2033
	mwexec(kill_hostapd("{$if}"));
2034
	mwexec(kill_wpasupplicant("{$if}"));
2035

    
2036
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2037
	conf_mount_rw();
2038

    
2039
	switch ($wlcfg['mode']) {
2040
		case 'bss':
2041
			if (isset($wlcfg['wpa']['enable'])) {
2042
				$wpa .= <<<EOD
2043
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2044
ctrl_interface_group=0
2045
ap_scan=1
2046
#fast_reauth=1
2047
network={
2048
ssid="{$wlcfg['ssid']}"
2049
scan_ssid=1
2050
priority=5
2051
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2052
psk="{$wlcfg['wpa']['passphrase']}"
2053
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2054
group={$wlcfg['wpa']['wpa_pairwise']}
2055
}
2056
EOD;
2057

    
2058
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2059
				fwrite($fd, "{$wpa}");
2060
				fclose($fd);
2061
			}
2062
			break;
2063
		case 'hostap':
2064
			if($wlcfg['wpa']['passphrase']) 
2065
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2066
			else 
2067
				$wpa_passphrase = "";
2068
			if (isset($wlcfg['wpa']['enable'])) {
2069
				$wpa .= <<<EOD
2070
interface={$if}
2071
driver=bsd
2072
logger_syslog=-1
2073
logger_syslog_level=0
2074
logger_stdout=-1
2075
logger_stdout_level=0
2076
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2077
ctrl_interface={$g['varrun_path']}/hostapd
2078
ctrl_interface_group=wheel
2079
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2080
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2081
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2082
ssid={$wlcfg['ssid']}
2083
debug={$wlcfg['wpa']['debug_mode']}
2084
auth_algs={$wlcfg['wpa']['auth_algs']}
2085
wpa={$wlcfg['wpa']['wpa_mode']}
2086
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2087
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2088
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2089
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2090
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2091
{$wpa_passphrase}
2092
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2093
#rsn_preauth=1
2094
#rsn_preauth_interfaces=eth0
2095

    
2096
EOD;
2097

    
2098
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2099
					$auth_server_port = "1812";
2100
					if($wlcfg['auth_server_port']) 
2101
						$auth_server_port = $wlcfg['auth_server_port'];
2102
					$wpa .= <<<EOD
2103

    
2104
ieee8021x=1
2105
auth_server_addr={$wlcfg['auth_server_addr']}
2106
auth_server_port={$auth_server_port}
2107
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2108

    
2109
EOD;
2110
				} else {
2111
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2112
				}
2113

    
2114
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2115
				fwrite($fd, "{$wpa}");
2116
				fclose($fd);
2117

    
2118
			}
2119
			break;
2120
	}
2121

    
2122
	/*
2123
	 *    all variables are set, lets start up everything
2124
	 */
2125

    
2126
	$baseif = interface_get_wireless_base($if);
2127

    
2128
	/* set ack timers according to users preference (if he/she has any) */
2129
	if($distance) {
2130
		fwrite($fd_set, "# Enable ATH distance settings\n");
2131
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2132
	}
2133

    
2134
	if (isset($wlcfg['wpa']['enable'])) {
2135
		if ($wlcfg['mode'] == "bss") {
2136
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2137
		}
2138
		if ($wlcfg['mode'] == "hostap") {
2139
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
2140
		}
2141
	}
2142

    
2143
	fclose($fd_set);
2144
	conf_mount_ro();
2145

    
2146
	/* Making sure regulatory settings have actually changed
2147
	 * before applying, because changing them requires bringing
2148
	 * down all wireless networks on the interface. */
2149
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2150
	$ifconfig_str = implode($output);
2151
	unset($output);
2152
	$reg_changing = false;
2153

    
2154
	/* special case for the debug country code */
2155
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2156
		$reg_changing = true;
2157
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2158
		$reg_changing = true;
2159
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2160
		$reg_changing = true;
2161
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2162
		$reg_changing = true;
2163
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2164
		$reg_changing = true;
2165

    
2166
	if ($reg_changing) {
2167
		/* set regulatory domain */
2168
		if($wlcfg['regdomain'])
2169
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2170

    
2171
		/* set country */
2172
		if($wlcfg['regcountry'])
2173
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2174

    
2175
		/* set location */
2176
		if($wlcfg['reglocation'])
2177
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2178

    
2179
		$wlregcmd_args = implode(" ", $wlregcmd);
2180

    
2181
		/* build a complete list of the wireless clones for this interface */
2182
		$clone_list = array();
2183
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2184
			$clone_list[] = interface_get_wireless_clone($baseif);
2185
		if (is_array($config['wireless']['clone'])) {
2186
			foreach ($config['wireless']['clone'] as $clone) {
2187
				if ($clone['if'] == $baseif)
2188
					$clone_list[] = $clone['cloneif'];
2189
			}
2190
		}
2191

    
2192
		/* find which clones are up and bring them down */
2193
		$clones_up = array();
2194
		foreach ($clone_list as $clone_if) {
2195
			$clone_status = pfSense_get_interface_addresses($clone_if);
2196
			if ($clone_status['status'] == 'up') {
2197
				$clones_up[] = $clone_if;
2198
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2199
			}
2200
		}
2201

    
2202
		/* apply the regulatory settings */
2203
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2204

    
2205
		/* bring the clones back up that were previously up */
2206
		foreach ($clones_up as $clone_if) {
2207
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2208
		}
2209
	}
2210

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

    
2215
	/* configure wireless */
2216
	$wlcmd_args = implode(" ", $wlcmd);
2217
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2218

    
2219
	
2220
	sleep(1);
2221
	/* execute hostapd and wpa_supplicant if required in shell */
2222
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2223

    
2224
	return 0;
2225

    
2226
}
2227

    
2228
function kill_hostapd($interface) {
2229
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2230
}
2231

    
2232
function kill_wpasupplicant($interface) {
2233
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2234
}
2235

    
2236
function find_dhclient_process($interface) {
2237
	if($interface) {
2238
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
2239
	}
2240
	return $pid;
2241
}
2242

    
2243
function interface_configure($interface = "wan", $reloadall = false) {
2244
	global $config, $g;
2245
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2246

    
2247
	$wancfg = $config['interfaces'][$interface];
2248

    
2249
	$realif = get_real_interface($interface);
2250

    
2251
	if (!$g['booting']) {
2252
		/* remove all IPv4 addresses */
2253
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2254
			interface_bring_down($interface);
2255
	}
2256

    
2257
	/* wireless configuration? */
2258
	if (is_array($wancfg['wireless']))
2259
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2260

    
2261
	if ($wancfg['spoofmac']) {
2262
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
2263
			" link " . escapeshellarg($wancfg['spoofmac']));
2264

    
2265
                /*
2266
                 * All vlans need to spoof their parent mac address, too.  see
2267
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2268
                 */
2269
                if (is_array($config['vlans']['vlan'])) {
2270
                        foreach ($config['vlans']['vlan'] as $vlan) {
2271
                                if ($vlan['if'] == $realif)
2272
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2273
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2274
                        }
2275
                }
2276
	}  else {
2277
		$mac = get_interface_mac(get_real_interface($wancfg['if']));
2278
		if($mac == "ff:ff:ff:ff:ff:ff") {
2279
			/*   this is not a valid mac address.  generate a
2280
			 *   temporary mac address so the machine can get online.
2281
			 */
2282
			echo "Generating new MAC address.";
2283
			$random_mac = generate_random_mac_address();
2284
			mwexec("/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if'])) .
2285
				" link " . escapeshellarg($random_mac));
2286
			$wancfg['spoofmac'] = $random_mac;
2287
			write_config();
2288
			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");
2289
		}
2290
	}
2291

    
2292
	/* media */
2293
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2294
		$cmd = "/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if']));
2295
		if ($wancfg['media'])
2296
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2297
		if ($wancfg['mediaopt'])
2298
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2299
		mwexec($cmd);
2300
	}
2301
	if (!empty($wancfg['mtu']))
2302
		pfSense_interface_mtu($realif, $wancfg['mtu']);
2303

    
2304
	/* invalidate interface/ip/sn cache */
2305
	get_interface_arr(true);
2306
	unset($interface_ip_arr_cache[$realif]);
2307
	unset($interface_sn_arr_cache[$realif]);
2308

    
2309
	switch ($wancfg['ipaddr']) {
2310
		case 'carpdev-dhcp':
2311
			interface_carpdev_dhcp_configure($interface);
2312
			break;
2313
		case 'dhcp':
2314
			interface_dhcp_configure($interface);
2315
			break;
2316
		case 'pppoe':
2317
		case 'l2tp':
2318
		case 'pptp':
2319
		case 'ppp':
2320
			interface_ppps_configure($interface);
2321
			break;
2322
		default:
2323
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
2324
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2325
			} else if (substr($realif, 0, 3) == "gre") {
2326
				if (is_array($config['gres']['gre'])) {
2327
					foreach ($config['gres']['gre'] as $gre)
2328
						if ($gre['greif'] == $realif)
2329
							interface_gre_configure($gre);
2330
				}
2331
			} else if (substr($realif, 0, 3) == "gif") {
2332
				 if (is_array($config['gifs']['gif'])) {
2333
					foreach ($config['gifs']['gif'] as $gif)
2334
						if($gif['gifif'] == $interface)
2335
							interface_gif_configure($gif);
2336
				}
2337
			} else if (substr($realif, 0, 4) == "ovpn") {
2338
				/* XXX: Should be done anything?! */
2339
			}
2340

    
2341
			if (is_ipaddr($wancfg['gateway']))
2342
				file_put_contents("{$g['tmp_path']}/{$realif}_router", $wancfg['gateway']);
2343
			break;
2344
	}
2345

    
2346
	if(does_interface_exist($wancfg['if']))
2347
		interfaces_bring_up($wancfg['if']);
2348
 	
2349
	if (!$g['booting'])
2350
		interface_reload_carps($realif);
2351
	
2352
	if (!$g['booting']) {
2353
		unset($gre);
2354
		$gre = link_interface_to_gre($interface);
2355
		if (!empty($gre))
2356
			interface_gre_configure($gre);
2357

    
2358
		unset($gif);
2359
		$gif = link_interface_to_gif($interface);
2360
		if (!empty($gif))
2361
                       	interface_gif_configure($gif);
2362

    
2363
		unset($bridgetmp);
2364
		$bridgetmp = link_interface_to_bridge($interface);
2365
		if (!empty($bridgetmp))
2366
			interface_bridge_add_member($bridgetmp, $realif);
2367

    
2368
		link_interface_to_vips($interface, "update");
2369

    
2370
		if ($interface == "lan")
2371
			/* make new hosts file */
2372
			system_hosts_generate();
2373

    
2374
		if ($reloadall == true) {
2375

    
2376
			/* reconfigure static routes (kernel may have deleted them) */
2377
			system_routing_configure($interface);
2378

    
2379
			/* reload ipsec tunnels */
2380
			vpn_ipsec_configure();
2381

    
2382
			/* update dyndns */
2383
			services_dyndns_configure($interface);
2384

    
2385
			/* force DNS update */
2386
			services_dnsupdate_process($interface);
2387

    
2388
			/* restart dnsmasq */
2389
			services_dnsmasq_configure();
2390

    
2391
			/* reload captive portal */
2392
			captiveportal_init_rules();
2393

    
2394
			/* set the reload filter dity flag */
2395
			filter_configure();
2396
		}
2397
	}
2398

    
2399
	return 0;
2400
}
2401

    
2402
function interface_carpdev_dhcp_configure($interface = "wan") {
2403
	global $config, $g;
2404

    
2405
	$wancfg = $config['interfaces'][$interface];
2406
	$wanif = $wancfg['if'];
2407
	/* bring wan interface up before starting dhclient */
2408
	if($wanif)
2409
		interfaces_bring_up($wanif);
2410
	else 
2411
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2412

    
2413
	return 0;
2414
}
2415

    
2416
function interface_dhcp_configure($interface = "wan") {
2417
	global $config, $g;
2418

    
2419
	$wancfg = $config['interfaces'][$interface];
2420
	if (empty($wancfg))
2421
		$wancfg = array();
2422

    
2423
	/* generate dhclient_wan.conf */
2424
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2425
	if (!$fd) {
2426
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2427
		return 1;
2428
	}
2429

    
2430
	if ($wancfg['dhcphostname']) {
2431
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2432
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2433
	} else {
2434
		$dhclientconf_hostname = "";
2435
	}
2436

    
2437
	$wanif = get_real_interface($interface);
2438
	if (empty($wanif)) {
2439
		log_error("Invalid interface \"{$interface}\" in interface_dhcp_configure()");
2440
		return 0;
2441
	}
2442
 	$dhclientconf = "";
2443
	
2444
	$dhclientconf .= <<<EOD
2445
interface "{$wanif}" {
2446
timeout 60;
2447
retry 1;
2448
select-timeout 0;
2449
initial-interval 1;
2450
	{$dhclientconf_hostname}
2451
	script "/sbin/dhclient-script";
2452
}
2453

    
2454
EOD;
2455

    
2456
if(is_ipaddr($wancfg['alias-address'])) {
2457
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2458
	$dhclientconf .= <<<EOD
2459
alias {
2460
	interface  "{$wanif}";
2461
	fixed-address {$wancfg['alias-address']};
2462
	option subnet-mask {$subnetmask};
2463
}
2464

    
2465
EOD;
2466
}
2467
	fwrite($fd, $dhclientconf);
2468
	fclose($fd);
2469

    
2470
	/* bring wan interface up before starting dhclient */
2471
	if($wanif)
2472
		interfaces_bring_up($wanif);
2473
	else 
2474
		log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
2475

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

    
2479
	return 0;
2480
}
2481

    
2482
function interfaces_group_setup() {
2483
	global $config;
2484

    
2485
	if (!is_array($config['ifgroups']['ifgroupentry']))
2486
		return;
2487

    
2488
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2489
		interface_group_setup($groupar);
2490

    
2491
	return;
2492
}
2493

    
2494
function interface_group_setup(&$groupname /* The parameter is an array */) {
2495
	global $config;
2496

    
2497
	if (!is_array($groupname))
2498
		return;
2499
	$members = explode(" ", $groupname['members']);
2500
	foreach($members as $ifs) {
2501
		$realif = get_real_interface($ifs);
2502
		if ($realif)
2503
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2504
	}
2505

    
2506
	return;
2507
}
2508
 
2509
/* COMPAT Function */
2510
function convert_friendly_interface_to_real_interface_name($interface) {
2511
	return get_real_interface($interface);
2512
}
2513

    
2514
/* COMPAT Function */
2515
function get_real_wan_interface($interface = "wan") {
2516
	return get_real_interface($interface);
2517
}
2518

    
2519
/* COMPAT Function */
2520
function get_current_wan_address($interface = "wan") {
2521
	return get_interface_ip($interface);
2522
}
2523

    
2524
/*
2525
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2526
 */
2527
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2528
        global $config;
2529

    
2530
	if (stristr($interface, "vip")) {
2531
                $index = intval(substr($interface, 3));
2532
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2533
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2534
                                if ($index == $counter)
2535
                                        return $vip['interface'];
2536
                        }
2537
                }
2538
        } else if (stristr($interface, "carp")) {
2539
                $index = intval(substr($interface, 4));
2540
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2541
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2542
                                if ($index == $counter)
2543
                                        return $vip['interface'];
2544
                        }
2545
                }
2546
        }
2547

    
2548
        /* XXX: For speed reasons reference directly the interface array */
2549
	$ifdescrs = $config['interfaces'];
2550
        //$ifdescrs = get_configured_interface_list(false, true);
2551

    
2552
        foreach ($ifdescrs as $if => $ifname) {
2553
                if ($config['interfaces'][$if]['if'] == $interface)
2554
                        return $if;
2555

    
2556
                if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
2557
                        return $if;
2558

    
2559
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2560
                $int = interface_translate_type_to_real($if);
2561
                if ($int == $interface)
2562
                        return $ifname;
2563
        }
2564
        return NULL;
2565
}
2566

    
2567
/* attempt to resolve interface to friendly descr */
2568
function convert_friendly_interface_to_friendly_descr($interface) {
2569
        global $config;
2570

    
2571
        switch ($interface) {
2572
                case "l2tp":
2573
                                $ifdesc = "L2TP";
2574
                                break;
2575
                case "pptp":
2576
                                $ifdesc = "PPTP";
2577
                                break;
2578
                case "pppoe":
2579
                                $ifdesc = "PPPoE";
2580
                                break;
2581
                case "openvpn":
2582
                                $ifdesc = "OpenVPN";
2583
                                break;
2584
                case "enc0":
2585
                        case "ipsec":
2586
                                $ifdesc = "IPsec";
2587
                                break;
2588
        default:
2589
                if (isset($config['interfaces'][$interface])) {
2590
                        if (empty($config['interfaces'][$interface]['descr']))
2591
                                $ifdesc = strtoupper($interface);
2592
                        else
2593
                                $ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
2594
			break;
2595
		}
2596
                /* if list */
2597
                $ifdescrs = get_configured_interface_with_descr(false, true);
2598
                foreach ($ifdescrs as $if => $ifname) {
2599
                                if ($if == $interface || $ifname == $interface)
2600
                                        return $ifname;
2601
                }
2602
                break;
2603
        }
2604

    
2605
        return $ifdesc;
2606
}
2607

    
2608
function convert_real_interface_to_friendly_descr($interface) {
2609
        global $config;
2610

    
2611
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2612

    
2613
        if ($ifdesc) {
2614
                $iflist = get_configured_interface_with_descr(false, true);
2615
                return $iflist[$ifdesc];
2616
        }
2617

    
2618
        return $interface;
2619
}
2620

    
2621
/*
2622
 *  interface_translate_type_to_real($interface):
2623
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2624
 */
2625
function interface_translate_type_to_real($interface) {
2626
        global $config;
2627

    
2628
        if ($config['interfaces'][$interface]['if'] <> "")
2629
                return $config['interfaces'][$interface]['if'];
2630
        else
2631
		return $interface;
2632
}
2633

    
2634
function interface_is_wireless_clone($wlif) {
2635
	if(!stristr($wlif, "_wlan")) {
2636
		return false;
2637
	} else {
2638
		return true;
2639
	}
2640
}
2641

    
2642
function interface_get_wireless_base($wlif) {
2643
	if(!stristr($wlif, "_wlan")) {
2644
		return $wlif;
2645
	} else {
2646
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2647
	}
2648
}
2649

    
2650
function interface_get_wireless_clone($wlif) {
2651
	if(!stristr($wlif, "_wlan")) {
2652
		return $wlif . "_wlan0";
2653
	} else {
2654
		return $wlif;
2655
	}
2656
}
2657

    
2658
function get_real_interface($interface = "wan") {
2659
    global $config;
2660

    
2661
	$wanif = NULL;
2662

    
2663
	switch ($interface) {
2664
	case "l2tp":
2665
		$wanif = "l2tp";
2666
		break;
2667
	case "pptp":
2668
		$wanif = "pptp";
2669
		break;
2670
	case "pppoe":
2671
		$wanif = "pppoe";
2672
		break;
2673
	case "openvpn":
2674
		$wanif = "openvpn";
2675
		break;
2676
	case "ipsec":
2677
	case "enc0":
2678
		$wanif = "enc0";
2679
		break;
2680
	case "ppp":
2681
		$wanif = "ppp";
2682
		break;
2683
	default:
2684
		// If a real interface was alread passed simply
2685
		// pass the real interface back.  This encourages
2686
		// the usage of this function in more cases so that
2687
		// we can combine logic for more flexibility.
2688
		if(does_interface_exist($interface)) {
2689
			$wanif = $interface;
2690
			break;
2691
		}
2692
		if (empty($config['interfaces'][$interface]))
2693
			break;
2694

    
2695
		$cfg =& $config['interfaces'][$interface];
2696

    
2697
		// Wireless cloned NIC support (FreeBSD 8+)
2698
		// interface name format: $parentnic_wlanparentnic#
2699
		// example: ath0_wlan0
2700
		if (is_interface_wireless($cfg['if'])) {
2701
			$wanif = interface_get_wireless_clone($cfg['if']);
2702
			break;
2703
		}
2704
		/*
2705
		if (empty($cfg['if'])) {
2706
			$wancfg = $cfg['if'];
2707
			break;
2708
		}
2709
		*/
2710

    
2711
		switch ($cfg['ipaddr']) {
2712
			case "carpdev-dhcp":
2713
				$viparr = &$config['virtualip']['vip'];
2714
				if(is_array($viparr))
2715
				foreach ($viparr as $counter => $vip) {
2716
					if ($vip['mode'] == "carpdev-dhcp") {
2717
						if($vip['interface'] == $interface) {
2718
							$wanif = "carp{$counter}";
2719
							break;
2720
						}
2721
					}
2722
				}
2723
				break;
2724
			case "pppoe": 
2725
			case "pptp": 
2726
			case "l2tp": 
2727
			case "ppp":
2728
				$wanif = $cfg['if'];
2729
				break;
2730
			default:
2731
				$wanif = $cfg['if'];
2732
				break;
2733
		}
2734
		break;
2735
	}
2736

    
2737
    return $wanif;
2738
}
2739

    
2740
/* Guess the physical interface by providing a IP address */
2741
function guess_interface_from_ip($ipaddress) {
2742
	if(! is_ipaddr($ipaddress)) {
2743
		return false;
2744
	}
2745
	/* create a route table we can search */
2746
	exec("netstat -rnW", $output, $ret);
2747
	foreach($output as $line) {
2748
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
2749
			$fields = preg_split("/[ ]+/", $line);
2750
			if(ip_in_subnet($ipaddress, $fields[0])) {
2751
				return $fields[6];
2752
			}
2753
		}
2754
	}
2755
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
2756
	if(empty($ret)) {
2757
        	return false;
2758
	}
2759
	return $ret;
2760
}
2761

    
2762
/*
2763
 * find_ip_interface($ip): return the interface where an ip is defined
2764
 */
2765
function find_ip_interface($ip)
2766
{
2767
        /* if list */
2768
        $ifdescrs = get_configured_interface_list();
2769

    
2770
        foreach ($ifdescrs as $ifdescr => $ifname) {
2771
		if ($ip == get_interface_ip($ifname)) {
2772
                	$int = get_real_interface($ifname);
2773
			return $int;
2774
		}
2775
        }
2776
        return false;
2777
}
2778

    
2779
/*
2780
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
2781
 */
2782
function find_number_of_created_carp_interfaces() {
2783
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
2784
}
2785

    
2786
function get_all_carp_interfaces() {
2787
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
2788
	$ints = explode(" ", $ints);
2789
	return $ints;
2790
}
2791

    
2792
/*
2793
 * find_carp_interface($ip): return the carp interface where an ip is defined
2794
 */
2795
function find_carp_interface($ip) {
2796
	global $config;
2797
	if (is_array($config['virtualip']['vip'])) {
2798
		foreach ($config['virtualip']['vip'] as $vip) {
2799
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2800
				$carp_ip = get_interface_ip($vip['interface']);
2801
				$if = `ifconfig | grep '$ip ' -B1 | head -n1 | cut -d: -f1`;
2802
				if ($if)
2803
					return $if;
2804
			}
2805
		}
2806
	}
2807
}
2808

    
2809
function link_carp_interface_to_parent($interface) {
2810
        global $config;
2811

    
2812
        if ($interface == "")
2813
                return;
2814

    
2815
        $carp_ip = get_interface_ip($interface);
2816
        if (!is_ipaddr($carp_ip))
2817
                return;
2818

    
2819
        /* if list */
2820
        $ifdescrs = get_configured_interface_list();
2821
        foreach ($ifdescrs as $ifdescr => $ifname) {
2822
                $interfaceip = get_interface_ip($ifname);
2823
                $subnet_bits = get_interface_subnet($ifname);
2824
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
2825
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
2826
                        return $ifname;
2827
        }
2828

    
2829
        return "";
2830
}
2831

    
2832
/****f* interfaces/link_ip_to_carp_interface
2833
 * NAME
2834
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
2835
 * INPUTS
2836
 *   $ip
2837
 * RESULT
2838
 *   $carp_ints
2839
 ******/
2840
function link_ip_to_carp_interface($ip) {
2841
        global $config;
2842

    
2843
        if (!is_ipaddr($ip))
2844
                return;
2845

    
2846
        $carp_ints = "";
2847
        if (is_array($config['virtualip']['vip'])) {
2848
		$first = 0;
2849
		$carp_int = array();
2850
                foreach ($config['virtualip']['vip'] as $vip) {
2851
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2852
                                $carp_ip = $vip['subnet'];
2853
                                $carp_sn = $vip['subnet_bits'];
2854
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
2855
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
2856
					$carp_int[] = "vip{$vip['vhid']}";
2857
                        }
2858
                }
2859
		if (!empty($carp_int))
2860
			$carp_ints = implode(" ", array_unique($carp_int));
2861
        }
2862

    
2863
        return $carp_ints;
2864
}
2865

    
2866
function link_interface_to_vlans($int, $action = "") {
2867
	global $config;
2868

    
2869
	if (empty($int))
2870
		return;
2871

    
2872
	if (is_array($config['vlans']['vlan'])) {
2873
                foreach ($config['vlans']['vlan'] as $vlan) {
2874
			if ($int == $vlan['if']) {
2875
				if ($action == "update") {
2876
					interfaces_bring_up($int);
2877
				} else if ($action == "")
2878
					return $vlan;
2879
			}
2880
		}
2881
	}
2882
}
2883

    
2884
function link_interface_to_vips($int, $action = "") {
2885
        global $config;
2886

    
2887
        if (is_array($config['virtualip']['vip']))
2888
                foreach ($config['virtualip']['vip'] as $vip)
2889
                        if ($int == $vip['interface']) {
2890
				if ($action == "update")
2891
					interfaces_vips_configure($int);
2892
				else
2893
                                	return $vip;
2894
			}
2895
}
2896

    
2897
/****f* interfaces/link_interface_to_bridge
2898
 * NAME
2899
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2900
 * INPUTS
2901
 *   $ip
2902
 * RESULT
2903
 *   bridge[0-99]
2904
 ******/
2905
function link_interface_to_bridge($int) {
2906
        global $config;
2907

    
2908
        if (is_array($config['bridges']['bridged'])) {
2909
                foreach ($config['bridges']['bridged'] as $bridge) {
2910
			if (in_array($int, explode(',', $bridge['members'])))
2911
                                return "{$bridge['bridgeif']}";
2912
		}
2913
	}
2914
}
2915

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

    
2919
        if (is_array($config['gres']['gre']))
2920
                foreach ($config['gres']['gre'] as $gre)
2921
                        if($gre['if'] == $interface)
2922
                                return $gre;
2923
}
2924

    
2925
function link_interface_to_gif($interface) {
2926
        global $config;
2927

    
2928
        if (is_array($config['gifs']['gif']))
2929
                foreach ($config['gifs']['gif'] as $gif)
2930
                        if($gif['if'] == $interface)
2931
                                return $gif;
2932
}
2933

    
2934
/*
2935
 * find_interface_ip($interface): return the interface ip (first found)
2936
 */
2937
function find_interface_ip($interface, $flush = false)
2938
{
2939
	global $interface_ip_arr_cache;
2940

    
2941
	$interface = str_replace("\n", "", $interface);
2942
	
2943
	if (!does_interface_exist($interface))
2944
		return;
2945

    
2946
	/* Setup IP cache */
2947
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2948
		$ifinfo = pfSense_get_interface_addresses($interface);
2949
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
2950
	}
2951

    
2952
	return $interface_ip_arr_cache[$interface];
2953
}
2954

    
2955
function find_interface_subnet($interface, $flush = false)
2956
{
2957
	global $interface_sn_arr_cache;
2958

    
2959
	$interface = str_replace("\n", "", $interface);
2960
	if (does_interface_exist($interface) == false)
2961
		return;
2962

    
2963
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2964
		$ifinfo = pfSense_get_interface_addresses($interface);
2965
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
2966
        }
2967

    
2968
	return $interface_sn_arr_cache[$interface];
2969
}
2970

    
2971
function get_interface_ip($interface = "wan")
2972
{
2973
	$realif = get_real_interface($interface);
2974
	if (!$realif) {
2975
		if (preg_match("/^carp/i", $interface))
2976
			$realif = $interface;
2977
		else if (preg_match("/^vip/i", $interface))
2978
			$realif = $interface;
2979
		else
2980
			return null;
2981
	}
2982

    
2983
	$curip = find_interface_ip($realif);
2984
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2985
		return $curip;
2986
	else
2987
		return null;
2988
}
2989

    
2990
function get_interface_subnet($interface = "wan")
2991
{
2992
	$realif = get_real_interface($interface);
2993
	if (!$realif) {
2994
                if (preg_match("/^carp/i", $interface))
2995
                        $realif = $interface;
2996
                else if (preg_match("/^vip/i", $interface))
2997
                        $realif = $interface;
2998
                else
2999
                        return null;
3000
        }
3001

    
3002
	$cursn = find_interface_subnet($realif);
3003
	if (!empty($cursn))
3004
		return $cursn;
3005

    
3006
	return null;
3007
}
3008

    
3009
/* return outside interfaces with a gateway */
3010
function get_interfaces_with_gateway() {
3011
	global $config;
3012

    
3013
	$ints = array();
3014

    
3015
	/* loop interfaces, check config for outbound */
3016
	foreach($config['interfaces'] as $ifdescr => $ifname) {
3017
		if (substr($ifdescr, 0, 5) ==  "ovpnc")
3018
			return true;
3019

    
3020
		switch ($ifname['ipaddr']) {
3021
			case "dhcp":
3022
			case "carpdev-dhcp":
3023
			case "ppp";
3024
			case "pppoe":
3025
			case "pptp":
3026
			case "l2tp":
3027
			case "ppp";
3028
				$ints[$ifdescr] = $ifdescr;
3029
			break;
3030
			default:
3031
				if (!empty($ifname['gateway']))
3032
					$ints[$ifdescr] = $ifdescr;
3033
			break;
3034
		}
3035
	}
3036
	return $ints;
3037
}
3038

    
3039
/* return true if interface has a gateway */
3040
function interface_has_gateway($friendly) {
3041
	global $config;
3042

    
3043
	if (!empty($config['interfaces'][$friendly])) {
3044
		if (substr($friendly, 0, 5) ==  "ovpnc")
3045
			return true;
3046
		$ifname =& $config['interfaces'][$friendly];
3047
		switch ($ifname['ipaddr']) {
3048
			case "dhcp":
3049
			case "carpdev-dhcp":
3050
			case "pppoe":
3051
			case "pptp":
3052
			case "l2tp":
3053
			case "ppp";
3054
				return true;
3055
			break;
3056
			default:
3057
				if (!empty($ifname['gateway']))
3058
					return true;
3059
			break;
3060
		}
3061
	}
3062

    
3063
	return false;
3064
}
3065

    
3066
/****f* interfaces/is_altq_capable
3067
 * NAME
3068
 *   is_altq_capable - Test if interface is capable of using ALTQ
3069
 * INPUTS
3070
 *   $int            - string containing interface name
3071
 * RESULT
3072
 *   boolean         - true or false
3073
 ******/
3074

    
3075
function is_altq_capable($int) {
3076
        /* Per:
3077
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3078
         * Only the following drivers have ALTQ support
3079
         */
3080
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3081
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3082
			"hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe",
3083
			"npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk",
3084
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3085
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", "ppp");
3086

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

    
3089
        if (in_array($int_family[0], $capable))
3090
                return true;
3091
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
3092
		return true;
3093
        else
3094
                return false;
3095
}
3096

    
3097
/****f* interfaces/is_interface_wireless
3098
 * NAME
3099
 *   is_interface_wireless - Returns if an interface is wireless
3100
 * RESULT
3101
 *   $tmp       - Returns if an interface is wireless
3102
 ******/
3103
function is_interface_wireless($interface) {
3104
        global $config, $g;
3105

    
3106
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3107
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3108
                if (preg_match($g['wireless_regex'], $interface)) {
3109
                        if (isset($config['interfaces'][$friendly]))
3110
                                $config['interfaces'][$friendly]['wireless'] = array();
3111
                        return true;
3112
                }
3113
                return false;
3114
        } else
3115
                return true;
3116
}
3117

    
3118
function get_wireless_modes($interface) {
3119
	/* return wireless modes and channels */
3120
	$wireless_modes = array();
3121

    
3122
	$wlif = interface_translate_type_to_real($interface);
3123

    
3124
	if(is_interface_wireless($wlif)) {
3125
		$cloned_interface = get_real_interface($interface);
3126
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3127
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3128
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3129

    
3130
		$interface_channels = "";
3131
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3132
		$interface_channel_count = count($interface_channels);
3133

    
3134
		$c = 0;
3135
		while ($c < $interface_channel_count)
3136
		{
3137
			$channel_line = explode(",", $interface_channels["$c"]);
3138
			$wireless_mode = trim($channel_line[0]);
3139
			$wireless_channel = trim($channel_line[1]);
3140
			if(trim($wireless_mode) != "") {
3141
				/* if we only have 11g also set 11b channels */
3142
				if($wireless_mode == "11g") {
3143
					if(!isset($wireless_modes["11b"]))
3144
						$wireless_modes["11b"] = array();
3145
				} else if($wireless_mode == "11g ht") {
3146
					if(!isset($wireless_modes["11b"]))
3147
						$wireless_modes["11b"] = array();
3148
					if(!isset($wireless_modes["11g"]))
3149
						$wireless_modes["11g"] = array();
3150
					$wireless_mode = "11ng";
3151
				} else if($wireless_mode == "11a ht") {
3152
					if(!isset($wireless_modes["11a"]))
3153
						$wireless_modes["11a"] = array();
3154
					$wireless_mode = "11na";
3155
				}
3156
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3157
			}
3158
			$c++;
3159
		}
3160
	}
3161
	return($wireless_modes);
3162
}
3163

    
3164
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3165
function get_wireless_channel_info($interface) {
3166
	$wireless_channels = array();
3167

    
3168
	$wlif = interface_translate_type_to_real($interface);
3169

    
3170
	if(is_interface_wireless($wlif)) {
3171
		$cloned_interface = get_real_interface($interface);
3172
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3173
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3174
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3175

    
3176
		$interface_channels = "";
3177
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3178

    
3179
		foreach ($interface_channels as $channel_line) {
3180
			$channel_line = explode(",", $channel_line);
3181
			if(!isset($wireless_channels[$channel_line[0]]))
3182
				$wireless_channels[$channel_line[0]] = $channel_line;
3183
		}
3184
	}
3185
	return($wireless_channels);
3186
}
3187

    
3188
/****f* interfaces/get_interface_mtu
3189
 * NAME
3190
 *   get_interface_mtu - Return the mtu of an interface
3191
 * RESULT
3192
 *   $tmp       - Returns the mtu of an interface
3193
 ******/
3194
function get_interface_mtu($interface) {
3195
        $mtu = pfSense_get_interface_addresses($interface);
3196
        return $mtu['mtu'];
3197
}
3198

    
3199
function get_interface_mac($interface) {
3200

    
3201
	$macinfo = pfSense_get_interface_addresses($interface);
3202
	return $macinfo["macaddr"];
3203
}
3204

    
3205
/****f* pfsense-utils/generate_random_mac_address
3206
 * NAME
3207
 *   generate_random_mac - generates a random mac address
3208
 * INPUTS
3209
 *   none
3210
 * RESULT
3211
 *   $mac - a random mac address
3212
 ******/
3213
function generate_random_mac_address() {
3214
        $mac = "02";
3215
        for($x=0; $x<5; $x++)
3216
                $mac .= ":" . dechex(rand(16, 255));
3217
        return $mac;
3218
}
3219

    
3220
/****f* interfaces/is_jumbo_capable
3221
 * NAME
3222
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3223
 * INPUTS
3224
 *   $int             - string containing interface name
3225
 * RESULT
3226
 *   boolean          - true or false
3227
 ******/
3228
function is_jumbo_capable($int) {
3229
        global $g;
3230

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

    
3233
        if (in_array($int_family[0], $g['vlan_long_frame']))
3234
                return true;
3235
        else
3236
                return false;
3237
}
3238

    
3239
function setup_pppoe_reset_file($pppif, $iface="") {
3240
	global $g;
3241
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3242

    
3243
	if(!empty($iface) && !empty($pppif)){
3244
		$cron_cmd = "#!/bin/sh\necho '<?php require(\"config.inc\"); require(\"interfaces.inc\"); interface_reconfigure({$iface}); log_error(\"PPPoE periodic reset executed on {$iface}\"); ?>' | /usr/local/bin/php -q";
3245
		file_put_contents($cron_file, $cron_cmd);
3246
		chmod($cron_file, 0700);
3247
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3248
	} else
3249
		unlink_if_exists($cron_file);
3250
}
3251

    
3252
?>
(21-21/51)