Project

General

Profile

Download (90.4 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
	interfaces_bring_up($interface);
477
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
478
}
479

    
480
function interfaces_lagg_configure() 
481
{
482
        global $config, $g;
483
		if($g['booting']) 
484
			echo "Configuring LAGG interfaces...";
485
        $i = 0;
486
		if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
487
			foreach ($config['laggs']['lagg'] as $lagg) {
488
				if(empty($lagg['laggif']))
489
					$lagg['laggif'] = "lagg{$i}";
490
				/* XXX: Maybe we should report any errors?! */
491
				interface_lagg_configure($lagg);
492
				$i++;
493
			}
494
		}
495
		if($g['booting']) 
496
			echo "done.\n";
497
}
498

    
499
function interface_lagg_configure(&$lagg) {
500
        global $config, $g;
501

    
502
        if (!is_array($lagg))
503
		return -1;
504

    
505
	$members = explode(',', $lagg['members']);
506
	if (!count($members))
507
		return -1;
508
	
509
	$checklist = get_interface_list();
510

    
511
	if ($g['booting'] || !(empty($lagg['laggif']))) {
512
		pfSense_interface_destroy($lagg['laggif']);
513
		pfSense_interface_create($lagg['laggif']);
514
                $laggif = $lagg['laggif'];
515
        } else
516
		$laggif = pfSense_interface_create("lagg");
517

    
518
	/* Calculate smaller mtu and enforce it */
519
        $smallermtu = 0;
520
        foreach ($members as $member) {
521
                $mtu = get_interface_mtu($member);
522
		if ($smallermtu == 0 && !empty($mtu))
523
			$smallermtu = $mtu;
524
                else if (!empty($mtu) && $mtu < $smallermtu)
525
                        $smallermtu = $mtu;
526
        }
527

    
528
	/* Just in case anything is not working well */
529
        if ($smallermtu == 0)
530
                $smallermtu = 1500;
531

    
532
	foreach ($members as $member) {
533
		if (!array_key_exists($member, $checklist))
534
			continue;
535
		/* make sure the parent interface is up */
536
		pfSense_interface_mtu($member, $smallermtu);
537
		interfaces_bring_up($member);
538
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
539
	}
540
	
541
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
542

    
543
	interfaces_bring_up($laggif);
544

    
545
	return $laggif;
546
}
547

    
548
function interfaces_gre_configure() {
549
        global $config;
550

    
551
        $i = 0;
552
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
553
                foreach ($config['gres']['gre'] as $gre) {
554
                        if(empty($gre['greif']))
555
                                $gre['greif'] = "gre{$i}";
556
                        /* XXX: Maybe we should report any errors?! */
557
                        interface_gre_configure($gre);
558
                        $i++;
559
                }
560
        }
561
}
562

    
563
function interface_gre_configure(&$gre) {
564
        global $config, $g;
565

    
566
	if (!is_array($gre))
567
		return -1;
568

    
569
	$realif = get_real_interface($gre['if']);
570
	$realifip = get_interface_ip($gre['if']);
571

    
572
	/* make sure the parent interface is up */
573
	interfaces_bring_up($realif);
574

    
575
	if ($g['booting'] || !(empty($gre['greif']))) {
576
		pfSense_interface_destroy($gre['greif']);
577
		pfSense_interface_create($gre['greif']);
578
		$greif = $gre['greif'];
579
	} else
580
		$greif = pfSense_interface_create("gre");
581

    
582
	/* Do not change the order here for more see gre(4) NOTES section. */
583
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
584
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
585
	if (isset($gre['link0']) && $gre['link0'])
586
		pfSense_interface_flags($greif, IFF_LINK0);
587
	if (isset($gre['link1']) && $gre['link1'])
588
		pfSense_interface_flags($greif, IFF_LINK1);
589
	if (isset($gre['link2']) && $gre['link2'])
590
		pfSense_interface_flags($greif, IFF_LINK2);
591

    
592
	if($greif)
593
		interfaces_bring_up($greif);
594
	else 
595
		log_error("Could not bring greif up -- variable not defined.");
596

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

    
601
	return $greif;
602
}
603

    
604
function interfaces_gif_configure() {
605
	global $config;
606
	$i = 0;
607
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
608
		foreach ($config['gifs']['gif'] as $gif) {
609
			if(empty($gif['gifif']))
610
				$gre['gifif'] = "gif{$i}";
611
			/* XXX: Maybe we should report any errors?! */
612
			interface_gif_configure($gif);
613
			$i++;
614
		}
615
	}
616
}
617

    
618
function interface_gif_configure(&$gif) {
619
	global $config, $g;
620

    
621
	if (!is_array($gif))
622
		return -1;
623

    
624
	$realif = get_real_interface($gif['if']);
625
	$realifip = get_interface_ip($gif['if']);
626

    
627
	/* make sure the parent interface is up */
628
	if($realif)
629
		interfaces_bring_up($realif);
630
	else 
631
		log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
632

    
633
	if ($g['booting'] || !(empty($gif['gifif']))) {
634
		pfSense_interface_destroy($gif['gifif']);
635
		pfSense_interface_create($gif['gifif']);
636
		$gifif = $gif['gifif'];
637
	} else
638
		$gifif = pfSense_interface_create("gif");
639

    
640
	/* Do not change the order here for more see gif(4) NOTES section. */
641
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
642
	mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
643
	if (isset($gif['link0']) && $gif['link0'])
644
		pfSense_interface_flags($gifif, IFF_LINK0);
645
	if (isset($gif['link1']) && $gif['link1'])
646
		pfSense_interface_flags($gifif, IFF_LINK1);
647
	if($gifif)
648
		interfaces_bring_up($gifif);
649
	else
650
		log_error("could not bring gifif up -- variable not defined");
651

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

    
656
	return $gifif;
657
}
658

    
659
function interfaces_configure() {
660
	global $config, $g;
661

    
662
	/* Set up our loopback interface */
663
	interfaces_loopback_configure();
664

    
665
	/* set up LAGG virtual interfaces */
666
	interfaces_lagg_configure();
667

    
668
	/* set up VLAN virtual interfaces */
669
	interfaces_vlan_configure();
670

    
671
	interfaces_qinq_configure();
672

    
673
	$iflist = get_configured_interface_with_descr();
674
	$delayed_list = array();
675
	$bridge_list = array();
676
	
677
	/* This is needed to speedup interfaces on bootup. */
678
	$reload = false;
679
	if ($g['booting'])
680
		$reload = true;
681

    
682
	foreach($iflist as $if => $ifname) {
683
		$realif = $config['interfaces'][$if]['if'];
684
		if (strstr($realif, "bridge")) 
685
			$bridge_list[$if] = $ifname;
686
		else if (strstr($realif, "gre"))
687
			$delayed_list[$if] = $ifname;
688
		else if (strstr($realif, "gif"))
689
			$delayed_list[$if] = $ifname;
690
		else {
691
			if ($g['booting'])
692
				echo "Configuring {$ifname} interface...";
693
			if($g['debug'])
694
				log_error("Configuring {$ifname}");
695
			interface_configure($if, $reload);
696
			if ($g['booting']) 
697
				echo "done.\n";
698
		}
699
	}
700

    
701
	/* create the unconfigured wireless clones */
702
	interfaces_create_wireless_clones();
703

    
704
	/* set up GRE virtual interfaces */
705
	interfaces_gre_configure();
706

    
707
	/* set up GIF virtual interfaces */
708
	interfaces_gif_configure();
709
	
710
	foreach ($delayed_list as $if => $ifname) {
711
		if ($g['booting'])
712
			echo "Configuring {$ifname} interface...";
713
        	if ($g['debug'])
714
        		log_error("Configuring {$ifname}");
715

    
716
		interface_configure($if, $reload);
717

    
718
		if ($g['booting'])
719
			echo "done.\n";
720
	}
721

    
722
	/* set up BRIDGe virtual interfaces */
723
	interfaces_bridge_configure();
724

    
725
	foreach ($bridge_list as $if => $ifname) {
726
		if ($g['booting'])
727
			echo "Configuring {$ifname} interface...";
728
		if($g['debug'])
729
			log_error("Configuring {$ifname}");
730

    
731
		interface_configure($if, $reload);
732

    
733
		if ($g['booting'])
734
			echo "done.\n";
735
	}
736

    
737
	/* bring up vip interfaces */
738
	interfaces_vips_configure();
739

    
740
	/* configure interface groups */
741
	interfaces_group_setup();
742

    
743
	if (!$g['booting']) {
744
		/* reconfigure static routes (kernel may have deleted them) */
745
		system_routing_configure();
746

    
747
		/* reload IPsec tunnels */
748
		vpn_ipsec_configure();
749

    
750
		/* reload dhcpd (interface enabled/disabled status may have changed) */
751
		services_dhcpd_configure();
752

    
753
		/* restart dnsmasq */
754
		services_dnsmasq_configure();
755

    
756
		/* reload captive portal */
757
		captiveportal_configure();
758

    
759
		/* set the reload filter dity flag */
760
		filter_configure();
761
	}
762

    
763
	return 0;
764
}
765

    
766
function interface_reconfigure($interface = "wan") {
767
	interface_bring_down($interface);
768
	interface_configure($interface, true);
769
}
770

    
771
function interface_vip_bring_down(&$vip) {
772
	switch ($vip['mode']) {
773
	case "proxyarp":
774
		interface_proxyarp_configure();
775
		break;
776
	case "ipalias":
777
		$vipif = get_real_interface($vip['interface']);
778
		if(does_interface_exist($vipif))
779
			pfSense_interface_deladdress($vipif, $vip['subnet']);
780
		break;
781
	case "carp":
782
		$vipif = "vip" . $vip['vhid'];
783
		if(does_interface_exist($vipif)) 
784
			pfSense_interface_destroy($vipif);
785
		break;
786
	case "carpdev-dhcp":
787
		$vipif = "vip" . $vip['vhid'];
788
		if(does_interface_exist($vipif)) 
789
			pfSense_interface_destroy($vipif);
790
		break;
791
	}
792
}
793

    
794
function interface_bring_down($interface = "wan", $destroy = false) {
795
	global $config, $g;
796

    
797
	if (!isset($config['interfaces'][$interface]))
798
		return; 
799

    
800
	$ifcfg = $config['interfaces'][$interface];
801

    
802
	$realif = get_real_interface($interface);
803

    
804
	switch ($ifcfg['ipaddr']) {
805
	case "ppp":
806
	case "pppoe":
807
	case "pptp":
808
	case "l2tp":
809
		killbypid("{$g['varrun_path']}/{$ifcfg['ipaddr']}_{$interface}.pid");
810
		sleep(2);
811
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
812
		break;
813
	case "carpdev-dhcp":
814
		/* 
815
		 * NB: When carpdev gets enabled it would be better to be handled as all
816
		 *	   other interfaces! 
817
		 */
818
	case "dhcp":
819
		$pid = find_dhclient_process($realif);
820
		if($pid)
821
			mwexec("kill {$pid}");
822
		sleep(1);
823
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
824
		if(does_interface_exist("$realif")) {
825
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
826
			pfSense_interface_flags($realif, -IFF_UP);
827
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
828
		}
829
		break;
830
	default:
831
		if(does_interface_exist("$realif")) {
832
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
833
			pfSense_interface_flags($realif, -IFF_UP);
834
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
835
		}
836
		break;
837
	}
838

    
839
	/* remove interface up file if it exists */
840
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
841
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
842
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
843
	
844
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
845
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
846
	if (is_array($ifcfg['wireless'])) {
847
		mwexec(kill_hostapd($realif));
848
		mwexec(kill_wpasupplicant($realif));
849
	}
850

    
851
	if ($destroy == true) {
852
		if (preg_match("/^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
853
			pfSense_interface_destroy($realif);
854
	}	
855

    
856
	return;
857
}
858

    
859
function interfaces_ptpid_used($ptpid) {
860
	global $config;
861

    
862
	if (is_array($config['ppps']['ppp']))
863
		foreach ($config['ppps']['ppp'] as & $settings)
864
			if ($ptpid == $settings['ptpid'])
865
				return true;
866

    
867
	return false;
868
}
869

    
870
function interfaces_ptpid_next() {
871

    
872
	$ptpid = 0;
873
	while(interfaces_ptpid_used($ptpid))
874
		$ptpid++;
875

    
876
	return $ptpid;
877
}
878

    
879
function getMPDCRONSettings($pppif_) {
880
	global $config;
881
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
882
	if (is_array($config['cron']['item'])) {
883
		for ($i = 0; $i < count($config['cron']['item']); $i++) {
884
			$item = $config['cron']['item'][$i];
885
			if (strpos($item['command'], $cron_cmd_file.$pppif_) !== false) {
886
				return array("ID" => $i, "ITEM" => $item);
887
			}
888
		}
889
	}
890
	return NULL;
891
}
892

    
893
function handle_pppoe_reset($post_array) {
894
	global $config, $g;
895

    
896
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
897

    
898
	$pppif = $post_array['type'].$post_array['ptpid'];
899
	if (!is_array($config['cron']['item'])) 
900
		$config['cron']['item'] = array(); 
901
	$itemhash = getMPDCRONSettings($pppif);
902
	$item = $itemhash['ITEM'];
903
	
904
	// reset cron items if necessary and return
905
	if (empty($post_array['pppoe-reset-type'])) {
906
		if (isset($item))
907
			unset($config['cron']['item'][$itemhash['ID']]);
908
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
909
		return;
910
	}
911

    
912
	if (empty($item)) 
913
		$item = array();
914
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
915
		$item['minute'] = $post_array['pppoe_resetminute'];
916
		$item['hour'] = $post_array['pppoe_resethour'];
917
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
918
			$date = explode("/", $post_array['pppoe_resetdate']);
919
			$item['mday'] = $date[1];
920
			$item['month'] = $date[0];
921
		} else {
922
			$item['mday'] = "*";
923
			$item['month'] = "*";
924
		}
925
		$item['wday'] = "*";
926
		$item['who'] = "root";
927
		$item['command'] = $cron_cmd_file.$pppif;
928
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
929
		switch ($post_array['pppoe_pr_preset_val']) {
930
			case "monthly":
931
				$item['minute'] = "0";
932
				$item['hour'] = "0";
933
				$item['mday'] = "1";
934
				$item['month'] = "*";
935
				$item['wday'] = "*";
936
				$item['who'] = "root";
937
				$item['command'] = $cron_cmd_file.$pppif;
938
				break;
939
	        case "weekly":
940
				$item['minute'] = "0";
941
				$item['hour'] = "0";
942
				$item['mday'] = "*";
943
				$item['month'] = "*";
944
				$item['wday'] = "0";
945
				$item['who'] = "root";
946
				$item['command'] = $cron_cmd_file.$pppif;
947
				break;
948
			case "daily":
949
				$item['minute'] = "0";
950
				$item['hour'] = "0";
951
				$item['mday'] = "*";
952
				$item['month'] = "*";
953
				$item['wday'] = "*";
954
				$item['who'] = "root";
955
				$item['command'] = $cron_cmd_file.$pppif;
956
				break;
957
			case "hourly":
958
				$item['minute'] = "0";
959
				$item['hour'] = "*";
960
				$item['mday'] = "*";
961
				$item['month'] = "*";
962
				$item['wday'] = "*";
963
				$item['who'] = "root";
964
				$item['command'] = $cron_cmd_file.$pppif;
965
				break;
966
		} // end switch
967
	} else {
968
		/* test whether a cron item exists and unset() it if necessary */
969
		$itemhash = getMPDCRONSettings($pppif);
970
		$item = $itemhash['ITEM'];
971
		if (isset($item))
972
			unset($config['cron']['item'][$itemhash['ID']]); 
973
	}// end if
974
	if (isset($itemhash['ID'])) 
975
		$config['cron']['item'][$itemhash['ID']] = $item;
976
	else 
977
		$config['cron']['item'][] = $item;
978
}
979

    
980
/*	This function can configure PPPoE, MLPPP (PPPoE), PPtP.
981
*	It writes the mpd config file to /var/etc every time the link is opened.
982
*/
983

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

    
1086
	/* generate mpd.conf */
1087
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1088
	if (!$fd) {
1089
		log_error("Error: cannot open mpd_{$interface}.conf in interface_ppps_configure().\n");
1090
		return 0;
1091
	}
1092
	
1093
	if (is_array($ports) && count($ports) > 1)
1094
		$multilink = "enable";
1095
	else
1096
		$multilink = "disable";
1097
	
1098
	if ($type == "modem"){
1099
		if (is_ipaddr($ppp['localip']))
1100
			$localip = $ppp['localip'];
1101
		else
1102
			$localip = '0.0.0.0';
1103

    
1104
		if (is_ipaddr($ppp['gateway']))
1105
			$gateway = $ppp['gateway'];
1106
		else
1107
			$gateway = "10.64.64.{$pppid}";
1108
		$ranges = "{$localip}/0 {$gateway}/0";
1109
		
1110
		if (empty($ppp['apnum']))	
1111
			$ppp['apnum'] = 1;
1112
	} else
1113
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1114

    
1115
	if (isset($ppp['ondemand'])) 
1116
		$ondemand = "enable";
1117
	else
1118
		$ondemand = "disable";
1119
	if (!isset($ppp['idletimeout']))
1120
		$ppp['idletimeout'] = 0;
1121

    
1122
	if (empty($ppp['username']) && $type == "modem"){
1123
		$ppp['username'] = "user";
1124
		$ppp['password'] = "none";
1125
	}
1126
	if (empty($ppp['password']) && $type == "modem")
1127
		$passwd = "none";
1128
	else
1129
		$passwd = base64_decode($ppp['password']);
1130

    
1131
	$bandwidths = explode(',',$ppp['bandwidth']);
1132
	$mtus = explode(',',$ppp['mtu']);
1133
	$mrus = explode(',',$ppp['mru']);
1134

    
1135
	if (isset($ppp['mrru']))
1136
		$mrrus = explode(',',$ppp['mrru']);
1137

    
1138
	// Construct the mpd.conf file
1139
	$mpdconf = <<<EOD
1140
startup:
1141
	# configure the console
1142
	set console close
1143
	# configure the web server
1144
	set web close
1145

    
1146
default:
1147
{$ppp['type']}client:
1148
	create bundle static {$interface}
1149
	set iface name {$pppif}
1150

    
1151
EOD;
1152
	$setdefaultgw = false;
1153
	$founddefaultgw = false;
1154
	if (is_array($config['gateways']['gateway_item'])) {
1155
		foreach($config['gateways']['gateway_item'] as $gateway) {
1156
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1157
				$setdefaultgw = true;
1158
				break;
1159
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1160
				$founddefaultgw = true;
1161
				break;
1162
			}
1163
		}
1164
	}
1165
	
1166
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1167
		$setdefaultgw = true;
1168
		$mpdconf .= <<<EOD
1169
	set iface route default
1170

    
1171
EOD;
1172
	}
1173
	$mpdconf .= <<<EOD
1174
	set iface {$ondemand} on-demand
1175
	set iface idle {$ppp['idletimeout']}
1176

    
1177
EOD;
1178

    
1179
	if (isset($ppp['ondemand']))
1180
		$mpdconf .= <<<EOD
1181
	set iface addrs 10.10.1.1 10.10.1.2
1182

    
1183
EOD;
1184
	
1185
	if (isset($ppp['tcpmssfix']))
1186
		$tcpmss = "disable";
1187
	else
1188
		$tcpmss = "enable";
1189
		$mpdconf .= <<<EOD
1190
	set iface {$tcpmss} tcpmssfix
1191

    
1192
EOD;
1193

    
1194
	$mpdconf .= <<<EOD
1195
	set iface up-script /usr/local/sbin/ppp-linkup
1196
	set iface down-script /usr/local/sbin/ppp-linkdown
1197
	set ipcp ranges {$ranges}
1198

    
1199
EOD;
1200
	if (isset($ppp['vjcomp']))
1201
		$mpdconf .= <<<EOD
1202
	set ipcp no vjcomp
1203

    
1204
EOD;
1205

    
1206
	if (isset($config['system']['dnsallowoverride']))
1207
		$mpdconf .= <<<EOD
1208
	set ipcp enable req-pri-dns
1209
	set ipcp enable req-sec-dns
1210

    
1211
EOD;
1212
	if (!isset($ppp['verbose_log']))
1213
		$mpdconf .= <<<EOD
1214
	log -bund -ccp -chat -iface -ipcp -lcp -link
1215

    
1216
EOD;
1217
	foreach($ports as $pid => $port){
1218
		$port = get_real_interface($port);
1219
		$mpdconf .= <<<EOD
1220

    
1221
	create link static {$interface}_link{$pid} {$type}
1222
	set link action bundle {$interface}
1223
	set link {$multilink} multilink
1224
	set link keep-alive 10 60
1225
	set link max-redial 0
1226

    
1227
EOD;
1228
		if (isset($ppp['shortseq']))
1229
			$mpdconf .= <<<EOD
1230
	set link no shortseq
1231

    
1232
EOD;
1233

    
1234
		if (isset($ppp['acfcomp']))
1235
			$mpdconf .= <<<EOD
1236
	set link no acfcomp
1237

    
1238
EOD;
1239

    
1240
		if (isset($ppp['protocomp']))
1241
			$mpdconf .= <<<EOD
1242
	set link no protocomp
1243

    
1244
EOD;
1245

    
1246
		$mpdconf .= <<<EOD
1247
	set link disable chap pap
1248
	set link accept chap pap eap
1249
	set link disable incoming
1250

    
1251
EOD;
1252

    
1253

    
1254
		if (!empty($bandwidths[$pid]))
1255
			$mpdconf .= <<<EOD
1256
	set link bandwidth {$bandwidths[$pid]}
1257

    
1258
EOD;
1259

    
1260
		if (empty($mtus[$pid]))
1261
			$mtus[$pid] = "1492";
1262
			$mpdconf .= <<<EOD
1263
	set link mtu {$mtus[$pid]}
1264

    
1265
EOD;
1266

    
1267
		if (!empty($mrus[$pid]))
1268
			$mpdconf .= <<<EOD
1269
	set link mru {$mrus[$pid]}
1270

    
1271
EOD;
1272

    
1273
		$mpdconf .= <<<EOD
1274
	set auth authname "{$ppp['username']}"
1275
	set auth password {$passwd}
1276

    
1277
EOD;
1278
		if ($type == "modem") {
1279
			$mpdconf .= <<<EOD
1280
	set modem device {$ppp['ports']}
1281
	set modem script DialPeer
1282
	set modem idle-script Ringback
1283
	set modem watch -cd
1284
	set modem var \$DialPrefix "DT"
1285
	set modem var \$Telephone "{$ppp['phone']}"
1286

    
1287
EOD;
1288
		}
1289
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1290
			$mpdconf .= <<<EOD
1291
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1292

    
1293
EOD;
1294
		}
1295
		if (isset($ppp['initstr']) && $type == "modem") {
1296
			$initstr = base64_decode($ppp['initstr']);
1297
			$mpdconf .= <<<EOD
1298
	set modem var \$InitString "{$initstr}"
1299

    
1300
EOD;
1301
		}
1302
		if (isset($ppp['simpin']) && $type == "modem") {
1303
			$mpdconf .= <<<EOD
1304
	set modem var \$SimPin "{$ppp['simpin']}"
1305
	set modem var \$PinWait "{$ppp['pin-wait']}"
1306

    
1307
EOD;
1308
		}
1309
		if (isset($ppp['apn']) && $type == "modem") {
1310
			$mpdconf .= <<<EOD
1311
	set modem var \$APN "{$ppp['apn']}"
1312
	set modem var \$APNum "{$ppp['apnum']}"
1313

    
1314
EOD;
1315
		}
1316
		if (isset($ppp['provider']) && $type == "pppoe") {
1317
			$mpdconf .= <<<EOD
1318
	set pppoe service "{$ppp['provider']}"
1319

    
1320
EOD;
1321
		}
1322
		if ($type == "pppoe")
1323
			$mpdconf .= <<<EOD
1324
	set pppoe iface {$port}
1325

    
1326
EOD;
1327

    
1328
		if ($type == "pptp" || $type == "l2tp") {
1329
			$mpdconf .= <<<EOD
1330
	set pptp self {$localips[$pid]}
1331
	set pptp peer {$gateways[$pid]}
1332
	set pptp disable windowing
1333

    
1334
EOD;
1335
		}
1336
		
1337
		$mpdconf .= "\topen\r\n";
1338
	} //end foreach($port)
1339

    
1340
	// Write out mpd_ppp.conf
1341
	fwrite($fd, $mpdconf);
1342
	fclose($fd);
1343

    
1344
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1345
	if (isset($ppp['uptime'])) {
1346
		if (!file_exists("/conf/{$pppif}.log")) {
1347
			conf_mount_rw();
1348
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1349
			conf_mount_ro();
1350
		}
1351
	} else {
1352
		if (file_exists("/conf/{$pppif}.log")) {
1353
			conf_mount_rw();
1354
			mwexec("rm -f /conf/{$pppif}.log");
1355
			conf_mount_ro();
1356
		}
1357
	}
1358
		
1359
	/* fire up mpd */
1360
	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");
1361

    
1362
	// Check for PPPoE periodic reset request 
1363
	if ($type == "pppoe") {
1364
		if (isset($ppp['pppoe-reset-type']))
1365
			setup_pppoe_reset_file($ppp['if'], $interface);
1366
		else
1367
			setup_pppoe_reset_file($ppp['if']);
1368
	}
1369

    
1370
	return 1;
1371
}
1372

    
1373
function interfaces_carp_setup() {
1374
	global $g, $config;
1375

    
1376
	$balanacing = "";
1377
	$pfsyncinterface = "";
1378
	$pfsyncenabled = "";
1379
	if(isset($config['system']['developerspew'])) {
1380
		$mt = microtime();
1381
		echo "interfaces_carp_setup() being called $mt\n";
1382
	}
1383

    
1384
	// Prepare CmdCHAIN that will be used to execute commands.
1385
	$cmdchain = new CmdCHAIN();	
1386

    
1387
	if ($g['booting']) {
1388
		echo "Configuring CARP settings...";
1389
		mute_kernel_msgs();
1390
	}
1391

    
1392
	/* suck in configuration items */
1393
	if($config['installedpackages']['carpsettings']) {
1394
		if($config['installedpackages']['carpsettings']['config']) {
1395
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1396
				$pfsyncenabled = $carp['pfsyncenabled'];
1397
				$balanacing = $carp['balancing'];
1398
				$pfsyncinterface = $carp['pfsyncinterface'];
1399
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1400
			}
1401
		}
1402
	} else {
1403
		unset($pfsyncinterface);
1404
		unset($balanacing);
1405
		unset($pfsyncenabled);
1406
	}
1407

    
1408
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1409
	if($balanacing) {
1410
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1411
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1412
	} else
1413
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1414

    
1415
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=2", true);
1416
	if (!empty($pfsyncinterface))
1417
		$carp_sync_int = get_real_interface($pfsyncinterface);
1418

    
1419
	if($g['booting']) {
1420
		/*    install rules to alllow pfsync to sync up during boot
1421
		 *    carp interfaces will remain down until the bootup sequence finishes
1422
		 */
1423
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1424
		if ($fd) {
1425
			fwrite($fd, "pass quick proto carp all keep state\n");
1426
			fwrite($fd, "pass quick proto pfsync all\n");
1427
			fwrite($fd, "pass out quick from any to any keep state\n");
1428
			fclose($fd);
1429
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1430
		} else
1431
			log_error("Could not create rules.boot file!");
1432
	}
1433

    
1434
	/* setup pfsync interface */
1435
	if($carp_sync_int and $pfsyncenabled) {
1436
		if (is_ipaddr($pfsyncpeerip))
1437
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1438
		else
1439
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1440
	} else
1441
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1442

    
1443
	if($config['virtualip']['vip'])
1444
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1445
	else
1446
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1447
	
1448
	if($g['debug'])
1449
		$cmdchain->setdebug(); // optional for verbose logging
1450

    
1451
	$cmdchain->execute();
1452
	$cmdchain->clear();
1453

    
1454
	if ($g['booting']) {
1455
		unmute_kernel_msgs();
1456
		echo "done.\n";
1457
	}
1458
}
1459

    
1460
function interface_proxyarp_configure() {
1461
	global $config, $g;
1462
	if(isset($config['system']['developerspew'])) {
1463
		$mt = microtime();
1464
		echo "interface_proxyarp_configure() being called $mt\n";
1465
	}
1466

    
1467
	/* kill any running choparp */
1468
	killbyname("choparp");
1469

    
1470
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1471
		$paa = array();
1472

    
1473
		/* group by interface */
1474
		foreach ($config['virtualip']['vip'] as $vipent) {
1475
			if ($vipent['mode'] === "proxyarp") {
1476
				if ($vipent['interface'])
1477
					$proxyif = $vipent['interface'];
1478
				else
1479
					$proxyif = "wan";
1480

    
1481
				if (!is_array($paa[$if]))
1482
					$paa[$proxyif] = array();
1483

    
1484
				$paa[$proxyif][] = $vipent;
1485
			}
1486
	}
1487

    
1488
	if (count($paa))
1489
		foreach ($paa as $paif => $paents) {
1490
			$paaifip = get_interface_ip($paif);
1491
			if (!(is_ipaddr($paaifip)))
1492
				continue;
1493
			$args = get_real_interface($paif) . " auto";
1494
			foreach ($paents as $paent) {
1495

    
1496
				if (isset($paent['subnet']))
1497
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1498
				else if (isset($paent['range']))
1499
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
1500
					$paent['range']['to']);
1501
			}
1502
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1503
		}
1504
	}
1505

    
1506
}
1507

    
1508
function interfaces_vips_configure($interface = "") {
1509
	global $g, $config;
1510
	if(isset($config['system']['developerspew'])) {
1511
		$mt = microtime();
1512
		echo "interfaces_vips_configure() being called $mt\n";
1513
	}
1514
	$paa = array();
1515
	if(is_array($config['virtualip']['vip'])) {
1516
		$carp_setuped = false;
1517
		$anyproxyarp = false;
1518
		foreach ($config['virtualip']['vip'] as $vip) {
1519
			switch ($vip['mode']) {
1520
			case "proxyarp":
1521
				/* nothing it is handled on interface_proxyarp_configure() */
1522
				if ($interface <> "" && $vip['interface'] <> $interface)
1523
					continue;
1524
				$anyproxyarp = true;
1525
				break;
1526
			case "ipalias":
1527
				if ($interface <> "" && $vip['interface'] <> $interface)
1528
					continue;
1529
				interface_ipalias_configure(&$vip);
1530
				break;
1531
			case "carp":
1532
				if ($interface <> "" && $vip['interface'] <> $interface)
1533
					continue;
1534
				if ($carp_setuped == false) {
1535
					interfaces_carp_setup();
1536
					$carp_setuped = true;
1537
				}
1538
				interface_carp_configure($vip);
1539
				break;
1540
			case "carpdev-dhcp":
1541
				if ($interface <> "" && $vip['interface'] <> $interface)
1542
					continue;
1543
				interface_carpdev_configure($vip);
1544
				break;
1545
			}
1546
		}
1547
		
1548
		if ($anyproxyarp == true)
1549
			interface_proxyarp_configure();
1550
	}
1551
}
1552

    
1553
function interface_ipalias_configure(&$vip) {
1554

    
1555
	if ($vip['mode'] == "ipalias") {
1556
		$if = get_real_interface($vip['interface']);
1557
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1558
	}
1559
}
1560

    
1561
function interface_reload_carps($cif) {
1562
	global $config;
1563

    
1564
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1565
	if (empty($carpifs))
1566
		return;
1567

    
1568
	$carps = explode(" ", $carpifs);
1569
	if(is_array($config['virtualip']['vip'])) {
1570
		$viparr = &$config['virtualip']['vip'];
1571
		foreach ($viparr as $vip) {
1572
			if (in_array($vip['carpif'], $carps)) {
1573
				switch ($vip['mode']) {
1574
					case "carp":
1575
					interface_vip_bring_down($vip);
1576
					sleep(1);
1577
					interface_carp_configure($vip);
1578
					break;
1579
					case "carpdev-dhcp":
1580
					interface_vip_bring_down($vip);
1581
					sleep(1);
1582
					interface_carpdev_configure($vip);
1583
					break;
1584
				}
1585
			}
1586
		}
1587
	}
1588
}
1589

    
1590
function interface_carp_configure(&$vip) {
1591
	global $config, $g;
1592
	if(isset($config['system']['developerspew'])) {
1593
		$mt = microtime();
1594
		echo "interface_carp_configure() being called $mt\n";
1595
	}
1596

    
1597
	if ($vip['mode'] != "carp")
1598
		return;
1599

    
1600
	$vip_password = $vip['password'];
1601
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1602
	if ($vip['password'] != "")
1603
		$password = " pass {$vip_password}";
1604

    
1605
	// set the vip interface to the vhid
1606
	$vipif = "vip{$vip['vhid']}";
1607

    
1608
	$interface = interface_translate_type_to_real($vip['interface']);
1609
	/*
1610
	 * ensure the interface containing the VIP really exists
1611
 	 * prevents a panic if the interface is missing or invalid
1612
	 */
1613
	$realif = get_real_interface($vip['interface']);
1614
	if (!does_interface_exist($realif)) {
1615
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1616
		return;
1617
	}
1618

    
1619
	/* ensure CARP IP really exists prior to loading up */
1620
	/* XXX: this can be bound to only the interface choosen in the carp creation. Not yet since upgrade is needed! */
1621
	$found = false;
1622
	$iflist = get_configured_interface_list();
1623
	foreach($iflist as $if) {
1624
		$ww_subnet_ip = get_interface_ip($if);
1625
		$ww_subnet_bits = get_interface_subnet($if);
1626
		if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits)) {
1627
			$found = true;
1628
			break;
1629
		}
1630
	}
1631
	if($found == false) {
1632
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1633
		return;
1634
	}
1635

    
1636
	/* invalidate interface cache */
1637
	get_interface_arr(true);
1638

    
1639
	/* create the carp interface and setup */
1640
	if (does_interface_exist($vipif)) {
1641
		pfSense_interface_flags($vipif, -IFF_UP);
1642
	} else {
1643
		$carpif = pfSense_interface_create("carp");
1644
		pfSense_interface_rename($carpif, $vipif);
1645
		pfSense_ngctl_name("{$carpif}:", $vipif);
1646
	}
1647

    
1648
	/* invalidate interface cache */
1649
	get_interface_arr(true);
1650

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

    
1654
	interfaces_bring_up($vipif);
1655
	
1656
	return $vipif;
1657
}
1658

    
1659
function interface_carpdev_configure(&$vip) {
1660
	global $g;
1661

    
1662
	if ($vip['mode'] != "carpdev-dhcp")
1663
		return;
1664

    
1665
	$vip_password = $vip['password'];
1666
	$vip_password = str_replace(" ", "", $vip_password);
1667
	if($vip['password'] != "")
1668
		$password = " pass \"" . $vip_password . "\"";
1669

    
1670
	log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1671
	if (empty($vip['interface']))
1672
		return;
1673

    
1674
	$vipif = "vip" . $vip['vhid'];
1675
	$realif = interface_translate_type_to_real($vip['interface']);
1676
	interfaces_bring_up($realif);
1677
	/*
1678
	 * ensure the interface containing the VIP really exists
1679
	 * prevents a panic if the interface is missing or invalid
1680
	 */
1681
	if (!does_interface_exist($realif)) {
1682
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1683
		return;
1684
	}
1685

    
1686
	if (does_interface_exist($vipif)) {
1687
		interface_bring_down($vipif);
1688
	} else {
1689
		$carpdevif = exec("/sbin/ifconfig carp create");
1690
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1691
		pfSense_ngctl_name("{$carpdevif}:", $vipif);
1692
	}
1693

    
1694
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1695
	interfaces_bring_up($vipif);
1696

    
1697
	/*
1698
	 * XXX: BIG HACK but carpdev needs ip services active
1699
	 *      before even starting something as dhclient.
1700
	 *      I do not know if this is a feature or a bug
1701
	 *      but better than track it make it work ;) .
1702
	 */
1703
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1704
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1705

    
1706
	/* generate dhclient_wan.conf */
1707
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1708
	if ($fd) {
1709
		$dhclientconf = "";
1710

    
1711
		$dhclientconf .= <<<EOD
1712
interface "{$vipif}" {
1713
timeout 60;
1714
retry 1;
1715
select-timeout 0;
1716
initial-interval 1;
1717
script "/sbin/dhclient-script";
1718
}
1719

    
1720
EOD;
1721

    
1722
		fwrite($fd, $dhclientconf);
1723
		fclose($fd);
1724

    
1725
		/* fire up dhclient */
1726
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} > {$g['tmp_path']}/{$vipif}_output > {$g['tmp_path']}/{$vipif}_error_output", false);
1727
	} else {
1728
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1729
		mwexec("/sbin/dhclient -b {$vipif}");
1730
	}
1731

    
1732
	return $vipif;
1733
}
1734

    
1735
function interface_wireless_clone($realif, $wlcfg) {
1736
	global $config, $g;
1737
	/*   Check to see if interface has been cloned as of yet.  
1738
	 *   If it has not been cloned then go ahead and clone it.
1739
	 */
1740
	$needs_clone = false;
1741
	if(is_array($wlcfg['wireless']))
1742
		$wlcfg_mode = $wlcfg['wireless']['mode'];
1743
	else
1744
		$wlcfg_mode = $wlcfg['mode'];
1745
	switch($wlcfg_mode) {
1746
		 case "hostap":
1747
			$mode = "wlanmode hostap";
1748
			break;
1749
		 case "adhoc":
1750
			$mode = "wlanmode adhoc";
1751
			break;
1752
		 default:
1753
			$mode = "";
1754
			break;
1755
	}
1756
	$baseif = interface_get_wireless_base($wlcfg['if']);
1757
	if(does_interface_exist($realif)) {
1758
		exec("/sbin/ifconfig {$realif}", $output, $ret);
1759
		$ifconfig_str = implode($output);
1760
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
1761
			log_error("Interface {$realif} changed to hostap mode");
1762
			$needs_clone = true;
1763
		}
1764
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
1765
			log_error("Interface {$realif} changed to adhoc mode");
1766
			$needs_clone = true;
1767
		}
1768
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
1769
			log_error("Interface {$realif} changed to infrastructure mode");
1770
			$needs_clone = true;
1771
		}
1772
	} else {
1773
		$needs_clone = true;
1774
	}
1775

    
1776
	if($needs_clone == true) {
1777
		/* remove previous instance if it exists */
1778
		if(does_interface_exist($realif))
1779
			pfSense_interface_destroy($realif);
1780

    
1781
		log_error("Cloning new wireless interface {$realif}");
1782
		// Create the new wlan interface. FreeBSD returns the new interface name.
1783
		// example:  wlan2
1784
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1785
		if($ret <> 0) {
1786
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1787
			return false;
1788
		}
1789
		$newif = trim($out[0]);
1790
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1791
		pfSense_interface_rename($newif, $realif);
1792
		// FIXME: not sure what ngctl is for. Doesn't work.
1793
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1794
	}
1795
	return true;
1796
}
1797

    
1798
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1799
	global $config, $g;
1800

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

    
1803
	if(!is_interface_wireless($ifcfg['if']))
1804
		return;
1805

    
1806
	$baseif = interface_get_wireless_base($ifcfg['if']);
1807

    
1808
	$iflist = get_configured_interface_list(false, true);
1809
	foreach ($iflist as $if) {
1810
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
1811
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
1812
				foreach ($shared_settings as $setting) {
1813
					if ($sync_changes) {
1814
						$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
1815
					} else {
1816
						$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
1817
					}
1818
				}
1819
				if (!$sync_changes)
1820
					break;
1821
			}
1822
		}
1823
	}
1824

    
1825
	if (interface_is_wireless_clone($ifcfg['if'])) {
1826
		foreach ($config['wireless']['clone'] as &$clone) {
1827
			if ($clone['cloneif'] == $ifcfg['if']) {
1828
				if ($sync_changes) {
1829
					$clone['mode'] = $ifcfg['wireless']['mode'];
1830
				} else {
1831
					$ifcfg['wireless']['mode'] = $clone['mode'];
1832
				}
1833
				break;
1834
			}
1835
		}
1836
		unset($clone);
1837
	}
1838
}
1839

    
1840
function interface_wireless_configure($if, &$wl, &$wlcfg) {
1841
	global $config, $g;
1842

    
1843
	/*    open up a shell script that will be used to output the commands.
1844
	 *    since wireless is changing a lot, these series of commands are fragile
1845
     *    and will sometimes need to be verified by a operator by executing the command
1846
     *    and returning the output of the command to the developers for inspection.  please
1847
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1848
	 */
1849

    
1850
	// Remove script file
1851
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1852

    
1853
	// Clone wireless nic if needed.
1854
	interface_wireless_clone($if, $wl);
1855

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

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

    
1863
	/* set values for /path/program */
1864
	$hostapd = "/usr/sbin/hostapd";
1865
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1866
	$ifconfig = "/sbin/ifconfig";
1867
	$killall = "/usr/bin/killall";
1868

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

    
1871
	$wlcmd = array();
1872
	/* Make sure it's up */
1873
	$wlcmd[] = "up";
1874
	/* Set a/b/g standard */
1875
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
1876
	$wlcmd[] = "mode " . escapeshellarg($standard);
1877

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

    
1883
	/* Set ssid */
1884
	if($wlcfg['ssid'])
1885
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
1886

    
1887
	/* Set 802.11g protection mode */
1888
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
1889

    
1890
	/* set wireless channel value */
1891
	if(isset($wlcfg['channel'])) {
1892
		if($wlcfg['channel'] == "0") {
1893
			$wlcmd[] = "channel any";
1894
		} else {
1895
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
1896
		}
1897
	}
1898

    
1899
	/* set Distance value */
1900
	if($wlcfg['distance'])
1901
		$distance = escapeshellarg($wlcfg['distance']);
1902

    
1903
	/* Set wireless hostap mode */
1904
	if ($wlcfg['mode'] == "hostap") {
1905
		$wlcmd[] = "mediaopt hostap";
1906
	} else {
1907
		$wlcmd[] = "-mediaopt hostap";
1908
	}
1909

    
1910
	/* Set wireless adhoc mode */
1911
	if ($wlcfg['mode'] == "adhoc") {
1912
		$wlcmd[] = "mediaopt adhoc";
1913
	} else {
1914
		$wlcmd[] = "-mediaopt adhoc";
1915
	}
1916

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

    
1919
	/* handle hide ssid option */
1920
	if(isset($wlcfg['hidessid']['enable'])) {
1921
		$wlcmd[] = "hidessid";
1922
	} else {
1923
		$wlcmd[] = "-hidessid";
1924
	}
1925

    
1926
	/* handle pureg (802.11g) only option */
1927
	if(isset($wlcfg['pureg']['enable'])) {
1928
		$wlcmd[] = "mode 11g pureg";
1929
	} else {
1930
		$wlcmd[] = "-pureg";
1931
	}
1932

    
1933
	/* handle puren (802.11n) only option */
1934
	if(isset($wlcfg['puren']['enable'])) {
1935
		$wlcmd[] = "puren";
1936
	} else {
1937
		$wlcmd[] = "-puren";
1938
	}
1939

    
1940
	/* enable apbridge option */
1941
	if(isset($wlcfg['apbridge']['enable'])) {
1942
		$wlcmd[] = "apbridge";
1943
	} else {
1944
		$wlcmd[] = "-apbridge";
1945
	}
1946

    
1947
	/* handle turbo option */
1948
	if(isset($wlcfg['turbo']['enable'])) {
1949
		$wlcmd[] = "mediaopt turbo";
1950
	} else {
1951
		$wlcmd[] = "-mediaopt turbo";
1952
	}
1953

    
1954
	/* handle txpower setting */
1955
	/* if($wlcfg['txpower'] <> "")
1956
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
1957
	*/
1958
	/* handle wme option */
1959
	if(isset($wlcfg['wme']['enable'])) {
1960
		$wlcmd[] = "wme";
1961
	} else {
1962
		$wlcmd[] = "-wme";
1963
	}
1964

    
1965
	/* set up wep if enabled */
1966
	$wepset = "";
1967
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
1968
		switch($wlcfg['wpa']['auth_algs']) {
1969
			case "1":
1970
				$wepset .= "authmode open wepmode on ";
1971
				break;
1972
			case "2":
1973
				$wepset .= "authmode shared wepmode on ";
1974
				break;
1975
			case "3":
1976
				$wepset .= "authmode mixed wepmode on ";
1977
		}
1978
		$i = 1;
1979
		foreach ($wlcfg['wep']['key'] as $wepkey) {
1980
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
1981
			if (isset($wepkey['txkey'])) {
1982
				$wlcmd[] = "weptxkey {$i} ";
1983
			}
1984
			$i++;
1985
		}
1986
		$wlcmd[] = $wepset;
1987
	} else {
1988
		$wlcmd[] = "authmode open wepmode off ";
1989
	}
1990

    
1991
	mwexec(kill_hostapd("{$if}"));
1992
	mwexec(kill_wpasupplicant("{$if}"));
1993

    
1994
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1995
	conf_mount_rw();
1996

    
1997
	switch ($wlcfg['mode']) {
1998
		case 'bss':
1999
			if (isset($wlcfg['wpa']['enable'])) {
2000
				$wpa .= <<<EOD
2001
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2002
ctrl_interface_group=0
2003
ap_scan=1
2004
#fast_reauth=1
2005
network={
2006
ssid="{$wlcfg['ssid']}"
2007
scan_ssid=1
2008
priority=5
2009
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2010
psk="{$wlcfg['wpa']['passphrase']}"
2011
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2012
group={$wlcfg['wpa']['wpa_pairwise']}
2013
}
2014
EOD;
2015

    
2016
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2017
				fwrite($fd, "{$wpa}");
2018
				fclose($fd);
2019
			}
2020
			break;
2021
		case 'hostap':
2022
			if($wlcfg['wpa']['passphrase']) 
2023
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2024
			else 
2025
				$wpa_passphrase = "";
2026
			if (isset($wlcfg['wpa']['enable'])) {
2027
				$wpa .= <<<EOD
2028
interface={$if}
2029
driver=bsd
2030
logger_syslog=-1
2031
logger_syslog_level=0
2032
logger_stdout=-1
2033
logger_stdout_level=0
2034
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2035
ctrl_interface={$g['varrun_path']}/hostapd
2036
ctrl_interface_group=wheel
2037
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2038
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2039
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2040
ssid={$wlcfg['ssid']}
2041
debug={$wlcfg['wpa']['debug_mode']}
2042
auth_algs={$wlcfg['wpa']['auth_algs']}
2043
wpa={$wlcfg['wpa']['wpa_mode']}
2044
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2045
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2046
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2047
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2048
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2049
{$wpa_passphrase}
2050
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2051
#rsn_preauth=1
2052
#rsn_preauth_interfaces=eth0
2053

    
2054
EOD;
2055

    
2056
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2057
					$auth_server_port = "1812";
2058
					if($wlcfg['auth_server_port']) 
2059
						$auth_server_port = $wlcfg['auth_server_port'];
2060
					$wpa .= <<<EOD
2061

    
2062
ieee8021x=1
2063
auth_server_addr={$wlcfg['auth_server_addr']}
2064
auth_server_port={$auth_server_port}
2065
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2066

    
2067
EOD;
2068
				} else {
2069
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2070
				}
2071

    
2072
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2073
				fwrite($fd, "{$wpa}");
2074
				fclose($fd);
2075

    
2076
			}
2077
			break;
2078
	}
2079

    
2080
	/*
2081
	 *    all variables are set, lets start up everything
2082
	 */
2083

    
2084
	$baseif = interface_get_wireless_base($if);
2085

    
2086
	/* set ack timers according to users preference (if he/she has any) */
2087
	if($distance) {
2088
		fwrite($fd_set, "# Enable ATH distance settings\n");
2089
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2090
	}
2091

    
2092
	if (isset($wlcfg['wpa']['enable'])) {
2093
		if ($wlcfg['mode'] == "bss") {
2094
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2095
		}
2096
		if ($wlcfg['mode'] == "hostap") {
2097
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
2098
		}
2099
	}
2100

    
2101
	fclose($fd_set);
2102
	conf_mount_ro();
2103

    
2104
	/* Making sure regulatory settings have actually changed
2105
	 * before applying, because changing them requires bringing
2106
	 * down all wireless networks on the interface. */
2107
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2108
	$ifconfig_str = implode($output);
2109
	unset($output);
2110
	$reg_changing = false;
2111

    
2112
	if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2113
		$reg_changing = true;
2114
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2115
		$reg_changing = true;
2116
	/* anywhere needs a special case, since it is not included in the ifconfig output.
2117
	 * Do not combine this if with the one inside. */
2118
	else if ($wlcfg['reglocation'] == 'anywhere') {
2119
		if (preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2120
			$reg_changing = true;
2121
	} else if ($wlcfg['reglocation'] && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2122
		$reg_changing = true;
2123

    
2124
	/* special case for the debug country code */
2125
	if ($wlcfg['regcountry'] == 'DEBUG' && preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2126
		$reg_changing = false;
2127

    
2128
	if ($reg_changing) {
2129
		/* set regulatory domain */
2130
		if($wlcfg['regdomain'])
2131
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2132

    
2133
		/* set country */
2134
		if($wlcfg['regcountry'])
2135
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2136

    
2137
		/* set location */
2138
		if($wlcfg['reglocation'])
2139
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2140

    
2141
		$wlregcmd_args = implode(" ", $wlregcmd);
2142

    
2143
		/* build a complete list of the wireless clones for this interface */
2144
		$clone_list = array();
2145
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2146
			$clone_list[] = interface_get_wireless_clone($baseif);
2147
		if (is_array($config['wireless']['clone'])) {
2148
			foreach ($config['wireless']['clone'] as $clone) {
2149
				if ($clone['if'] == $baseif)
2150
					$clone_list[] = $clone['cloneif'];
2151
			}
2152
		}
2153

    
2154
		/* find which clones are up and bring them down */
2155
		$clones_up = array();
2156
		foreach ($clone_list as $clone_if) {
2157
			$clone_status = pfSense_get_interface_addresses($clone_if);
2158
			if ($clone_status['status'] == 'up') {
2159
				$clones_up[] = $clone_if;
2160
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2161
			}
2162
		}
2163

    
2164
		/* apply the regulatory settings */
2165
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2166

    
2167
		/* bring the clones back up that were previously up */
2168
		foreach ($clones_up as $clone_if) {
2169
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2170
		}
2171
	}
2172

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

    
2177
	/* configure wireless */
2178
	$wlcmd_args = implode(" ", $wlcmd);
2179
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2180

    
2181
	
2182
	sleep(1);
2183
	/* execute hostapd and wpa_supplicant if required in shell */
2184
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2185

    
2186
	return 0;
2187

    
2188
}
2189

    
2190
function kill_hostapd($interface) {
2191
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2192
}
2193

    
2194
function kill_wpasupplicant($interface) {
2195
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2196
}
2197

    
2198
function find_dhclient_process($interface) {
2199
	if($interface) {
2200
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
2201
	}
2202
	return $pid;
2203
}
2204

    
2205
function interface_configure($interface = "wan", $reloadall = false) {
2206
	global $config, $g;
2207
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2208

    
2209
	$wancfg = $config['interfaces'][$interface];
2210

    
2211
	$realif = get_real_interface($interface);
2212

    
2213
	if (!$g['booting']) {
2214
		/* remove all IPv4 addresses */
2215
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2216
			interface_bring_down($interface);
2217
	}
2218

    
2219
	/* wireless configuration? */
2220
	if (is_array($wancfg['wireless']))
2221
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2222

    
2223
	if ($wancfg['spoofmac']) {
2224
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
2225
			" link " . escapeshellarg($wancfg['spoofmac']));
2226

    
2227
                /*
2228
                 * All vlans need to spoof their parent mac address, too.  see
2229
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2230
                 */
2231
                if (is_array($config['vlans']['vlan'])) {
2232
                        foreach ($config['vlans']['vlan'] as $vlan) {
2233
                                if ($vlan['if'] == $realif)
2234
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2235
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2236
                        }
2237
                }
2238
	}  else {
2239
		$mac = get_interface_mac(get_real_interface($wancfg['if']));
2240
		if($mac == "ff:ff:ff:ff:ff:ff") {
2241
			/*   this is not a valid mac address.  generate a
2242
			 *   temporary mac address so the machine can get online.
2243
			 */
2244
			echo "Generating new MAC address.";
2245
			$random_mac = generate_random_mac_address();
2246
			mwexec("/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if'])) .
2247
				" link " . escapeshellarg($random_mac));
2248
			$wancfg['spoofmac'] = $random_mac;
2249
			write_config();
2250
			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");
2251
		}
2252
	}
2253

    
2254
	/* media */
2255
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2256
		$cmd = "/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if']));
2257
		if ($wancfg['media'])
2258
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2259
		if ($wancfg['mediaopt'])
2260
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2261
		mwexec($cmd);
2262
	}
2263
	if (!empty($wancfg['mtu']))
2264
		pfSense_interface_mtu($realif, $wancfg['mtu']);
2265

    
2266
	/* invalidate interface/ip/sn cache */
2267
	get_interface_arr(true);
2268
	unset($interface_ip_arr_cache[$realif]);
2269
	unset($interface_sn_arr_cache[$realif]);
2270

    
2271
	switch ($wancfg['ipaddr']) {
2272

    
2273
		case 'carpdev-dhcp':
2274
			interface_carpdev_dhcp_configure($interface);
2275
			break;
2276
		case 'dhcp':
2277
			interface_dhcp_configure($interface);
2278
			break;
2279
		case 'pppoe':
2280
		case 'l2tp':
2281
		case 'pptp':
2282
		case 'ppp':
2283
			interface_ppps_configure($interface);
2284
			break;
2285
		default:
2286
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
2287
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2288
			} else if (substr($realif, 0, 3) == "gre") {
2289
				if (is_array($config['gres']['gre'])) {
2290
					foreach ($config['gres']['gre'] as $gre)
2291
						if ($gre['greif'] == $realif)
2292
							interface_gre_configure($gre);
2293
				}
2294
			} else if (substr($realif, 0, 3) == "gif") {
2295
				 if (is_array($config['gifs']['gif'])) {
2296
					foreach ($config['gifs']['gif'] as $gif)
2297
						if($gif['gifif'] == $interface)
2298
							interface_gif_configure($gif);
2299
				}
2300
			} else if (substr($realif, 0, 4) == "ovpn") {
2301
				/* XXX: Should be done anything?! */
2302
			}
2303

    
2304
			if (is_ipaddr($wancfg['gateway']))
2305
				file_put_contents("{$g['tmp_path']}/{$realif}_router", $wancfg['gateway']);
2306
			break;
2307
	}
2308

    
2309
	if(does_interface_exist($wancfg['if']))
2310
		interfaces_bring_up($wancfg['if']);
2311
 	
2312
	if (!$g['booting'])
2313
		interface_reload_carps($realif);
2314
	
2315
	if (!$g['booting']) {
2316
		if (link_interface_to_gre($interface)) {
2317
			foreach ($config['gres']['gre'] as $gre)
2318
				if ($gre['if'] == $interface)
2319
					interface_gre_configure($gre);
2320
		}
2321
		if (link_interface_to_gif($interface)) {
2322
                	foreach ($config['gifs']['gif'] as $gif)
2323
				if ($gif['if'] == $interface)
2324
                        		interface_gif_configure($gif);
2325
        	}
2326
		if (link_interface_to_bridge($interface)) {
2327
			foreach ($config['bridges']['bridged'] as $bridge)
2328
				if (stristr($bridge['members'], "{$interface}"))
2329
					interface_bridge_add_member($bridge['bridgeif'], $realif);
2330
		}
2331

    
2332
		link_interface_to_vips($interface, "update");
2333

    
2334
		if ($interface == "lan")
2335
			/* make new hosts file */
2336
			system_hosts_generate();
2337

    
2338
		if ($reloadall == true) {
2339

    
2340
			/* reconfigure static routes (kernel may have deleted them) */
2341
			system_routing_configure();
2342

    
2343
			/* reload ipsec tunnels */
2344
			vpn_ipsec_configure();
2345

    
2346
			/* update dyndns */
2347
			services_dyndns_configure($interface);
2348

    
2349
			/* force DNS update */
2350
			services_dnsupdate_process($interface);
2351

    
2352
			/* restart dnsmasq */
2353
			services_dnsmasq_configure();
2354

    
2355
			/* reload captive portal */
2356
			captiveportal_configure();
2357

    
2358
			/* set the reload filter dity flag */
2359
			filter_configure();
2360
		}
2361
	}
2362

    
2363
	return 0;
2364
}
2365

    
2366
function interface_carpdev_dhcp_configure($interface = "wan") {
2367
	global $config, $g;
2368

    
2369
	$wancfg = $config['interfaces'][$interface];
2370
	$wanif = $wancfg['if'];
2371
	/* bring wan interface up before starting dhclient */
2372
	if($wanif)
2373
		interfaces_bring_up($wanif);
2374
	else 
2375
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2376

    
2377
	return 0;
2378
}
2379

    
2380
function interface_dhcp_configure($interface = "wan") {
2381
	global $config, $g;
2382

    
2383
	$wancfg = $config['interfaces'][$interface];
2384
	if (empty($wancfg))
2385
		$wancfg = array();
2386

    
2387
	/* generate dhclient_wan.conf */
2388
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2389
	if (!$fd) {
2390
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2391
		return 1;
2392
	}
2393

    
2394
	if ($wancfg['dhcphostname']) {
2395
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2396
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2397
	} else {
2398
		$dhclientconf_hostname = "";
2399
	}
2400

    
2401
	$wanif = get_real_interface($interface);
2402
	if (empty($wanif)) {
2403
		log_error("Invalid interface \"{$interface}\" in interface_dhcp_configure()");
2404
		return 0;
2405
	}
2406
 	$dhclientconf = "";
2407
	
2408
	$dhclientconf .= <<<EOD
2409
interface "{$wanif}" {
2410
timeout 60;
2411
retry 1;
2412
select-timeout 0;
2413
initial-interval 1;
2414
	{$dhclientconf_hostname}
2415
	script "/sbin/dhclient-script";
2416
}
2417

    
2418
EOD;
2419

    
2420
if(is_ipaddr($wancfg['alias-address'])) {
2421
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2422
	$dhclientconf .= <<<EOD
2423
alias {
2424
	interface  "{$wanif}";
2425
	fixed-address {$wancfg['alias-address']};
2426
	option subnet-mask {$subnetmask};
2427
}
2428

    
2429
EOD;
2430
}
2431
	fwrite($fd, $dhclientconf);
2432
	fclose($fd);
2433

    
2434
	/* bring wan interface up before starting dhclient */
2435
	if($wanif)
2436
		interfaces_bring_up($wanif);
2437
	else 
2438
		log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
2439

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

    
2443
	return 0;
2444
}
2445

    
2446
function interfaces_group_setup() {
2447
	global $config;
2448

    
2449
	if (!is_array($config['ifgroups']['ifgroupentry']))
2450
		return;
2451

    
2452
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2453
		interface_group_setup($groupar);
2454

    
2455
	return;
2456
}
2457

    
2458
function interface_group_setup(&$groupname /* The parameter is an array */) {
2459
	global $config;
2460

    
2461
	if (!is_array($groupname))
2462
		return;
2463
	$members = explode(" ", $groupname['members']);
2464
	foreach($members as $ifs) {
2465
		$realif = get_real_interface($ifs);
2466
		if ($realif)
2467
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2468
	}
2469

    
2470
	return;
2471
}
2472
 
2473
/* COMPAT Function */
2474
function convert_friendly_interface_to_real_interface_name($interface) {
2475
	return get_real_interface($interface);
2476
}
2477

    
2478
/* COMPAT Function */
2479
function get_real_wan_interface($interface = "wan") {
2480
	return get_real_interface($interface);
2481
}
2482

    
2483
/* COMPAT Function */
2484
function get_current_wan_address($interface = "wan") {
2485
	return get_interface_ip($interface);
2486
}
2487

    
2488
/*
2489
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2490
 */
2491
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2492
        global $config;
2493

    
2494
	if (stristr($interface, "vip")) {
2495
                $index = intval(substr($interface, 3));
2496
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2497
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2498
                                if ($index == $counter)
2499
                                        return $vip['interface'];
2500
                        }
2501
                }
2502
        } else if (stristr($interface, "carp")) {
2503
                $index = intval(substr($interface, 4));
2504
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2505
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2506
                                if ($index == $counter)
2507
                                        return $vip['interface'];
2508
                        }
2509
                }
2510
        }
2511

    
2512
        /* XXX: For speed reasons reference directly the interface array */
2513
	$ifdescrs = $config['interfaces'];
2514
        //$ifdescrs = get_configured_interface_list(false, true);
2515

    
2516
        foreach ($ifdescrs as $if => $ifname) {
2517
                if ($config['interfaces'][$if]['if'] == $interface)
2518
                        return $if;
2519

    
2520
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2521
                $int = interface_translate_type_to_real($if);
2522
                if ($int == $interface)
2523
                        return $ifname;
2524
        }
2525
        return NULL;
2526
}
2527

    
2528
/* attempt to resolve interface to friendly descr */
2529
function convert_friendly_interface_to_friendly_descr($interface) {
2530
        global $config;
2531

    
2532
        switch ($interface) {
2533
                case "l2tp":
2534
                                $ifdesc = "L2TP";
2535
                                break;
2536
                case "pptp":
2537
                                $ifdesc = "pptp";
2538
                                break;
2539
                case "pppoe":
2540
                                $ifdesc = "pppoe";
2541
                                break;
2542
                case "openvpn":
2543
                                $ifdesc = "OpenVPN";
2544
                                break;
2545
                case "enc0":
2546
                        case "ipsec":
2547
                                $ifdesc = "IPsec";
2548
                                break;
2549
        default:
2550
                /* if list */
2551
                $ifdescrs = get_configured_interface_with_descr(false, true);
2552
                foreach ($ifdescrs as $if => $ifname) {
2553
                                if ($if == $interface || $ifname == $interface)
2554
                                        return $ifname;
2555
                }
2556
                break;
2557
        }
2558

    
2559
        return $ifdesc;
2560
}
2561

    
2562
function convert_real_interface_to_friendly_descr($interface) {
2563
        global $config;
2564

    
2565
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2566

    
2567
        if ($ifdesc) {
2568
                $iflist = get_configured_interface_with_descr(false, true);
2569
                return $iflist[$ifdesc];
2570
        }
2571

    
2572
        return $interface;
2573
}
2574

    
2575
/*
2576
 *  interface_translate_type_to_real($interface):
2577
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2578
 */
2579
function interface_translate_type_to_real($interface) {
2580
        global $config;
2581

    
2582
        if ($config['interfaces'][$interface]['if'] <> "")
2583
                return $config['interfaces'][$interface]['if'];
2584
        else
2585
		return $interface;
2586
}
2587

    
2588
function interface_is_wireless_clone($wlif) {
2589
	if(!stristr($wlif, "_wlan")) {
2590
		return false;
2591
	} else {
2592
		return true;
2593
	}
2594
}
2595

    
2596
function interface_get_wireless_base($wlif) {
2597
	if(!stristr($wlif, "_wlan")) {
2598
		return $wlif;
2599
	} else {
2600
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2601
	}
2602
}
2603

    
2604
function interface_get_wireless_clone($wlif) {
2605
	if(!stristr($wlif, "_wlan")) {
2606
		return $wlif . "_wlan0";
2607
	} else {
2608
		return $wlif;
2609
	}
2610
}
2611

    
2612
function get_real_interface($interface = "wan") {
2613
    global $config;
2614

    
2615
	$wanif = NULL;
2616

    
2617
	switch ($interface) {
2618
	case "l2tp":
2619
		$wanif = "l2tp";
2620
		break;
2621
	case "pptp":
2622
		$wanif = "pptp";
2623
		break;
2624
	case "pppoe":
2625
		$wanif = "pppoe";
2626
		break;
2627
	case "openvpn":
2628
		$wanif = "openvpn";
2629
		break;
2630
	case "ipsec":
2631
	case "enc0":
2632
		$wanif = "enc0";
2633
		break;
2634
	case "ppp":
2635
		$wanif = "ppp";
2636
		break;
2637
	default:
2638
		// If a real interface was alread passed simply
2639
		// pass the real interface back.  This encourages
2640
		// the usage of this function in more cases so that
2641
		// we can combine logic for more flexibility.
2642
		if(does_interface_exist($interface)) {
2643
			$wanif = $interface;
2644
			break;
2645
		}
2646
		if (empty($config['interfaces'][$interface]))
2647
			break;
2648

    
2649
		$cfg =& $config['interfaces'][$interface];
2650

    
2651
		// Wireless cloned NIC support (FreeBSD 8+)
2652
		// interface name format: $parentnic_wlanparentnic#
2653
		// example: ath0_wlan0
2654
		if (is_interface_wireless($cfg['if'])) {
2655
			$wanif = interface_get_wireless_clone($cfg['if']);
2656
			break;
2657
		}
2658
		/*
2659
		if (empty($cfg['if'])) {
2660
			$wancfg = $cfg['if'];
2661
			break;
2662
		}
2663
		*/
2664

    
2665
		switch ($cfg['ipaddr']) {
2666
			case "carpdev-dhcp":
2667
				$viparr = &$config['virtualip']['vip'];
2668
				if(is_array($viparr))
2669
				foreach ($viparr as $counter => $vip) {
2670
					if ($vip['mode'] == "carpdev-dhcp") {
2671
						if($vip['interface'] == $interface) {
2672
							$wanif = "carp{$counter}";
2673
							break;
2674
						}
2675
					}
2676
				}
2677
				break;
2678
			case "pppoe": 
2679
			case "pptp": 
2680
			case "l2tp": 
2681
			case "ppp":
2682
				$wanif = $cfg['if'];
2683
				break;
2684
			default:
2685
				$wanif = $cfg['if'];
2686
				break;
2687
		}
2688
		break;
2689
	}
2690

    
2691
    return $wanif;
2692
}
2693

    
2694
/* Guess the physical interface by providing a IP address */
2695
function guess_interface_from_ip($ipaddress) {
2696
	if(! is_ipaddr($ipaddress)) {
2697
		return false;
2698
	}
2699
	/* create a route table we can search */
2700
	exec("netstat -rnW", $output, $ret);
2701
	foreach($output as $line) {
2702
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
2703
			$fields = preg_split("/[ ]+/", $line);
2704
			if(ip_in_subnet($ipaddress, $fields[0])) {
2705
				return $fields[6];
2706
			}
2707
		}
2708
	}
2709
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
2710
	if(empty($ret)) {
2711
        	return false;
2712
	}
2713
	return $ret;
2714
}
2715

    
2716
/*
2717
 * find_ip_interface($ip): return the interface where an ip is defined
2718
 */
2719
function find_ip_interface($ip)
2720
{
2721
        /* if list */
2722
        $ifdescrs = get_configured_interface_list();
2723

    
2724
        foreach ($ifdescrs as $ifdescr => $ifname) {
2725
		if ($ip == get_interface_ip($ifname)) {
2726
                	$int = get_real_interface($ifname);
2727
			return $int;
2728
		}
2729
        }
2730
        return false;
2731
}
2732

    
2733
/*
2734
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
2735
 */
2736
function find_number_of_created_carp_interfaces() {
2737
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
2738
}
2739

    
2740
function get_all_carp_interfaces() {
2741
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
2742
	return $ints;
2743
}
2744

    
2745
/*
2746
 * find_carp_interface($ip): return the carp interface where an ip is defined
2747
 */
2748
function find_carp_interface($ip) {
2749
	global $config;
2750
	if (is_array($config['virtualip']['vip'])) {
2751
		foreach ($config['virtualip']['vip'] as $vip) {
2752
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2753
				$carp_ip = get_interface_ip($vip['interface']);
2754
				$if = `ifconfig | grep '$ip' -B1 | head -n1 | cut -d: -f1`;
2755
				if ($if)
2756
					return $if;
2757
			}
2758
		}
2759
	}
2760
}
2761

    
2762
function link_carp_interface_to_parent($interface) {
2763
        global $config;
2764

    
2765
        if ($interface == "")
2766
                return;
2767

    
2768
        $carp_ip = get_interface_ip($interface);
2769
        if (!is_ipaddr($carp_ip))
2770
                return;
2771

    
2772
        /* if list */
2773
        $ifdescrs = get_configured_interface_list();
2774
        foreach ($ifdescrs as $ifdescr => $ifname) {
2775
                $interfaceip = get_interface_ip($ifname);
2776
                $subnet_bits = get_interface_subnet($ifname);
2777
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
2778
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
2779
                        return $ifname;
2780
        }
2781

    
2782
        return "";
2783
}
2784

    
2785
/****f* interfaces/link_ip_to_carp_interface
2786
 * NAME
2787
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
2788
 * INPUTS
2789
 *   $ip
2790
 * RESULT
2791
 *   $carp_ints
2792
 ******/
2793
function link_ip_to_carp_interface($ip) {
2794
        global $config;
2795

    
2796
        if (!is_ipaddr($ip))
2797
                return;
2798

    
2799
        $carp_ints = "";
2800
        if (is_array($config['virtualip']['vip'])) {
2801
		$first = 0;
2802
		$carp_int = array();
2803
                foreach ($config['virtualip']['vip'] as $vip) {
2804
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2805
                                $carp_ip = $vip['subnet'];
2806
                                $carp_sn = $vip['subnet_bits'];
2807
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
2808
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
2809
					$carp_int[] = "vip{$vip['vhid']}";
2810
                        }
2811
                }
2812
		if (!empty($carp_int))
2813
			$carp_ints = implode(" ", array_unique($carp_int));
2814
        }
2815

    
2816
        return $carp_ints;
2817
}
2818

    
2819
function link_interface_to_vlans($int, $action = "") {
2820
	global $config;
2821

    
2822
	if (empty($int))
2823
		return;
2824

    
2825
	if (is_array($config['vlans']['vlan'])) {
2826
                foreach ($config['vlans']['vlan'] as $vlan) {
2827
			if ($int == $vlan['if']) {
2828
				if ($action == "update") {
2829
					interfaces_bring_up($int);
2830
				} else if ($action == "")
2831
					return $vlan;
2832
			}
2833
		}
2834
	}
2835
}
2836

    
2837
function link_interface_to_vips($int, $action = "") {
2838
        global $config;
2839

    
2840
        if (is_array($config['virtualip']['vip']))
2841
                foreach ($config['virtualip']['vip'] as $vip)
2842
                        if ($int == $vip['interface']) {
2843
				if ($action == "update")
2844
					interfaces_vips_configure($int);
2845
				else
2846
                                	return $vip;
2847
			}
2848
}
2849

    
2850
/****f* interfaces/link_interface_to_bridge
2851
 * NAME
2852
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2853
 * INPUTS
2854
 *   $ip
2855
 * RESULT
2856
 *   bridge[0-99]
2857
 ******/
2858
function link_interface_to_bridge($int) {
2859
        global $config;
2860

    
2861
        if (is_array($config['bridges']['bridged']))
2862
                foreach ($config['bridges']['bridged'] as $bridge)
2863
                        if(stristr($bridge['members'], "{$int}"))
2864
                                return "{$bridge['bridgeif']}";
2865
}
2866

    
2867
function link_interface_to_gre($interface) {
2868
        global $config;
2869

    
2870
        if (is_array($config['gres']['gre']))
2871
                foreach ($config['gres']['gre'] as $gre)
2872
                        if($gre['if'] == $interface)
2873
                                return "{$gre['greif']}";
2874
}
2875

    
2876
function link_interface_to_gif($interface) {
2877
        global $config;
2878

    
2879
        if (is_array($config['gifs']['gif']))
2880
                foreach ($config['gifs']['gif'] as $gif)
2881
                        if($gif['if'] == $interface)
2882
                                return "{$gif['gifif']}";
2883
}
2884

    
2885
/*
2886
 * find_interface_ip($interface): return the interface ip (first found)
2887
 */
2888
function find_interface_ip($interface, $flush = false)
2889
{
2890
	global $interface_ip_arr_cache;
2891

    
2892
	$interface = str_replace("\n", "", $interface);
2893
	
2894
	if (!does_interface_exist($interface))
2895
		return;
2896

    
2897
	/* Setup IP cache */
2898
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2899
		$ifinfo = pfSense_get_interface_addresses($interface);
2900
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
2901
	}
2902

    
2903
	return $interface_ip_arr_cache[$interface];
2904
}
2905

    
2906
function find_interface_subnet($interface, $flush = false)
2907
{
2908
	global $interface_sn_arr_cache;
2909

    
2910
	$interface = str_replace("\n", "", $interface);
2911
	if (does_interface_exist($interface) == false)
2912
		return;
2913

    
2914
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2915
		$ifinfo = pfSense_get_interface_addresses($interface);
2916
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
2917
        }
2918

    
2919
	return $interface_sn_arr_cache[$interface];
2920
}
2921

    
2922
function get_interface_ip($interface = "wan")
2923
{
2924
	$realif = get_real_interface($interface);
2925
	if (!$realif) {
2926
		if (preg_match("/^carp/i", $interface))
2927
			$realif = $interface;
2928
		else if (preg_match("/^vip/i", $interface))
2929
			$realif = $interface;
2930
		else
2931
			return null;
2932
	}
2933

    
2934
	$curip = find_interface_ip($realif);
2935
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2936
		return $curip;
2937
	else
2938
		return null;
2939
}
2940

    
2941
function get_interface_subnet($interface = "wan")
2942
{
2943
	$realif = get_real_interface($interface);
2944
	if (!$realif) {
2945
                if (preg_match("/^carp/i", $interface))
2946
                        $realif = $interface;
2947
                else if (preg_match("/^vip/i", $interface))
2948
                        $realif = $interface;
2949
                else
2950
                        return null;
2951
        }
2952

    
2953
	$cursn = find_interface_subnet($realif);
2954
	if (!empty($cursn))
2955
		return $cursn;
2956

    
2957
	return null;
2958
}
2959

    
2960
/* return outside interfaces with a gateway */
2961
function get_interfaces_with_gateway() {
2962
	global $config;
2963

    
2964
	$ints = array();
2965

    
2966
	/* loop interfaces, check config for outbound */
2967
	foreach($config['interfaces'] as $ifdescr => $ifname) {
2968

    
2969
		switch ($ifname['ipaddr']) {
2970
			case "dhcp":
2971
			case "carpdev-dhcp":
2972
			case "ppp";
2973
			case "pppoe":
2974
			case "pptp":
2975
			case "l2tp":
2976
			case "ppp";
2977
				$ints[$ifdescr] = $ifdescr;
2978
			break;
2979
			default:
2980
				if (!empty($ifname['gateway']))
2981
					$ints[$ifdescr] = $ifdescr;
2982
			break;
2983
		}
2984
	}
2985
	return $ints;
2986
}
2987

    
2988
/* return true if interface has a gateway */
2989
function interface_has_gateway($friendly) {
2990
	global $config;
2991

    
2992
	if (!empty($config['interfaces'][$friendly])) {
2993
		$ifname =& $config['interfaces'][$friendly];
2994
		switch ($ifname['ipaddr']) {
2995
			case "dhcp":
2996
			case "carpdev-dhcp":
2997
			case "pppoe":
2998
			case "pptp":
2999
			case "l2tp":
3000
			case "ppp";
3001
				return true;
3002
			break;
3003
			default:
3004
				if (!empty($ifname['gateway']))
3005
					return true;
3006
			break;
3007
		}
3008
	}
3009

    
3010
	return false;
3011
}
3012

    
3013
/****f* interfaces/is_altq_capable
3014
 * NAME
3015
 *   is_altq_capable - Test if interface is capable of using ALTQ
3016
 * INPUTS
3017
 *   $int            - string containing interface name
3018
 * RESULT
3019
 *   boolean         - true or false
3020
 ******/
3021

    
3022
function is_altq_capable($int) {
3023
        /* Per:
3024
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3025
         * Only the following drivers have ALTQ support
3026
         */
3027
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3028
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3029
			"hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe",
3030
			"npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk",
3031
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3032
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", "ppp");
3033

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

    
3036
        if (in_array($int_family[0], $capable))
3037
                return true;
3038
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
3039
		return true;
3040
        else
3041
                return false;
3042
}
3043

    
3044
/****f* interfaces/is_interface_wireless
3045
 * NAME
3046
 *   is_interface_wireless - Returns if an interface is wireless
3047
 * RESULT
3048
 *   $tmp       - Returns if an interface is wireless
3049
 ******/
3050
function is_interface_wireless($interface) {
3051
        global $config, $g;
3052

    
3053
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3054
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3055
                if (preg_match($g['wireless_regex'], $interface)) {
3056
                        $config['interfaces'][$friendly]['wireless'] = array();
3057
                        return true;
3058
                }
3059
                unset($config['interfaces'][$friendly]['wireless']);
3060
                return false;
3061
        } else
3062
                return true;
3063
}
3064

    
3065
function get_wireless_modes($interface) {
3066
	/* return wireless modes and channels */
3067
	$wireless_modes = array();
3068

    
3069
	$wlif = interface_translate_type_to_real($interface);
3070

    
3071
	if(is_interface_wireless($wlif)) {
3072
		$cloned_interface = get_real_interface($interface);
3073
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3074
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3075
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3076

    
3077
		$interface_channels = "";
3078
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3079
		$interface_channel_count = count($interface_channels);
3080

    
3081
		$c = 0;
3082
		while ($c < $interface_channel_count)
3083
		{
3084
			$channel_line = explode(",", $interface_channels["$c"]);
3085
			$wireless_mode = trim($channel_line[0]);
3086
			$wireless_channel = trim($channel_line[1]);
3087
			if(trim($wireless_mode) != "") {
3088
				/* if we only have 11g also set 11b channels */
3089
				if($wireless_mode == "11g") {
3090
					if(!isset($wireless_modes["11b"]))
3091
						$wireless_modes["11b"] = array();
3092
				} else if($wireless_mode == "11g ht") {
3093
					if(!isset($wireless_modes["11b"]))
3094
						$wireless_modes["11b"] = array();
3095
					if(!isset($wireless_modes["11g"]))
3096
						$wireless_modes["11g"] = array();
3097
					$wireless_mode = "11ng";
3098
				} else if($wireless_mode == "11a ht") {
3099
					if(!isset($wireless_modes["11a"]))
3100
						$wireless_modes["11a"] = array();
3101
					$wireless_mode = "11na";
3102
				}
3103
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3104
			}
3105
			$c++;
3106
		}
3107
	}
3108
	return($wireless_modes);
3109
}
3110

    
3111
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3112
function get_wireless_channel_info($interface) {
3113
	$wireless_channels = array();
3114

    
3115
	$wlif = interface_translate_type_to_real($interface);
3116

    
3117
	if(is_interface_wireless($wlif)) {
3118
		$cloned_interface = get_real_interface($interface);
3119
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3120
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3121
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3122

    
3123
		$interface_channels = "";
3124
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3125

    
3126
		foreach ($interface_channels as $channel_line) {
3127
			$channel_line = explode(",", $channel_line);
3128
			if(!isset($wireless_channels[$channel_line[0]]))
3129
				$wireless_channels[$channel_line[0]] = $channel_line;
3130
		}
3131
	}
3132
	return($wireless_channels);
3133
}
3134

    
3135
/****f* interfaces/get_interface_mtu
3136
 * NAME
3137
 *   get_interface_mtu - Return the mtu of an interface
3138
 * RESULT
3139
 *   $tmp       - Returns the mtu of an interface
3140
 ******/
3141
function get_interface_mtu($interface) {
3142
        $mtu = pfSense_get_interface_addresses($interface);
3143
        return $mtu['mtu'];
3144
}
3145

    
3146
function get_interface_mac($interface) {
3147

    
3148
	$macinfo = pfSense_get_interface_addresses($interface);
3149
	return $macinfo["macaddr"];
3150
}
3151

    
3152
/****f* pfsense-utils/generate_random_mac_address
3153
 * NAME
3154
 *   generate_random_mac - generates a random mac address
3155
 * INPUTS
3156
 *   none
3157
 * RESULT
3158
 *   $mac - a random mac address
3159
 ******/
3160
function generate_random_mac_address() {
3161
        $mac = "02";
3162
        for($x=0; $x<5; $x++)
3163
                $mac .= ":" . dechex(rand(16, 255));
3164
        return $mac;
3165
}
3166

    
3167
/****f* interfaces/is_jumbo_capable
3168
 * NAME
3169
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3170
 * INPUTS
3171
 *   $int             - string containing interface name
3172
 * RESULT
3173
 *   boolean          - true or false
3174
 ******/
3175
function is_jumbo_capable($int) {
3176
        global $g;
3177

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

    
3180
        if (in_array($int_family[0], $g['vlan_long_frame']))
3181
                return true;
3182
        else
3183
                return false;
3184
}
3185

    
3186
function setup_pppoe_reset_file($pppif, $iface="") {
3187
	global $g;
3188
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3189

    
3190
	if(!empty($iface) && !empty($pppif)){
3191
		$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";
3192
		file_put_contents($cron_file, $cron_cmd);
3193
		chmod($cron_file, 0700);
3194
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3195
	} else
3196
		unlink_if_exists($cron_file);
3197
}
3198

    
3199
?>
(21-21/50)