Project

General

Profile

Download (91.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
	pfSense_get_interface_addresses($bridgeif);
477
	if (isset($options['encaps']['txcsum']))
478
		pfSense_interface_capabilities($interface, -IFCAP_TXCSUM);
479
	else
480
		pfSense_interface_capabilities($interface, IFCAP_TXCSUM);
481

    
482
	interfaces_bring_up($interface);
483
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
484
}
485

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

    
505
function interface_lagg_configure(&$lagg) {
506
        global $config, $g;
507

    
508
        if (!is_array($lagg))
509
		return -1;
510

    
511
	$members = explode(',', $lagg['members']);
512
	if (!count($members))
513
		return -1;
514
	
515
	$checklist = get_interface_list();
516

    
517
	if ($g['booting'] || !(empty($lagg['laggif']))) {
518
		pfSense_interface_destroy($lagg['laggif']);
519
		pfSense_interface_create($lagg['laggif']);
520
                $laggif = $lagg['laggif'];
521
        } else
522
		$laggif = pfSense_interface_create("lagg");
523

    
524
	/* Calculate smaller mtu and enforce it */
525
        $smallermtu = 0;
526
        foreach ($members as $member) {
527
                $mtu = get_interface_mtu($member);
528
		if ($smallermtu == 0 && !empty($mtu))
529
			$smallermtu = $mtu;
530
                else if (!empty($mtu) && $mtu < $smallermtu)
531
                        $smallermtu = $mtu;
532
        }
533

    
534
	/* Just in case anything is not working well */
535
        if ($smallermtu == 0)
536
                $smallermtu = 1500;
537

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

    
549
	interfaces_bring_up($laggif);
550

    
551
	return $laggif;
552
}
553

    
554
function interfaces_gre_configure() {
555
        global $config;
556

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

    
569
function interface_gre_configure(&$gre) {
570
        global $config, $g;
571

    
572
	if (!is_array($gre))
573
		return -1;
574

    
575
	$realif = get_real_interface($gre['if']);
576
	$realifip = get_interface_ip($gre['if']);
577

    
578
	/* make sure the parent interface is up */
579
	interfaces_bring_up($realif);
580

    
581
	if ($g['booting'] || !(empty($gre['greif']))) {
582
		pfSense_interface_destroy($gre['greif']);
583
		pfSense_interface_create($gre['greif']);
584
		$greif = $gre['greif'];
585
	} else
586
		$greif = pfSense_interface_create("gre");
587

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

    
598
	if($greif)
599
		interfaces_bring_up($greif);
600
	else 
601
		log_error("Could not bring greif up -- variable not defined.");
602

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

    
607
	return $greif;
608
}
609

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

    
624
function interface_gif_configure(&$gif) {
625
	global $config, $g;
626

    
627
	if (!is_array($gif))
628
		return -1;
629

    
630
	$realif = get_real_interface($gif['if']);
631
	$realifip = get_interface_ip($gif['if']);
632

    
633
	/* make sure the parent interface is up */
634
	if($realif)
635
		interfaces_bring_up($realif);
636
	else 
637
		log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
638

    
639
	if ($g['booting'] || !(empty($gif['gifif']))) {
640
		pfSense_interface_destroy($gif['gifif']);
641
		pfSense_interface_create($gif['gifif']);
642
		$gifif = $gif['gifif'];
643
	} else
644
		$gifif = pfSense_interface_create("gif");
645

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

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

    
662
	return $gifif;
663
}
664

    
665
function interfaces_configure() {
666
	global $config, $g;
667

    
668
	/* Set up our loopback interface */
669
	interfaces_loopback_configure();
670

    
671
	/* set up LAGG virtual interfaces */
672
	interfaces_lagg_configure();
673

    
674
	/* set up VLAN virtual interfaces */
675
	interfaces_vlan_configure();
676

    
677
	interfaces_qinq_configure();
678

    
679
	$iflist = get_configured_interface_with_descr();
680
	$delayed_list = array();
681
	$bridge_list = array();
682
	
683
	/* This is needed to speedup interfaces on bootup. */
684
	$reload = false;
685
	if ($g['booting'])
686
		$reload = true;
687

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

    
707
	/* create the unconfigured wireless clones */
708
	interfaces_create_wireless_clones();
709

    
710
	/* set up GRE virtual interfaces */
711
	interfaces_gre_configure();
712

    
713
	/* set up GIF virtual interfaces */
714
	interfaces_gif_configure();
715
	
716
	foreach ($delayed_list as $if => $ifname) {
717
		if ($g['booting'])
718
			echo "Configuring {$ifname} interface...";
719
        	if ($g['debug'])
720
        		log_error("Configuring {$ifname}");
721

    
722
		interface_configure($if, $reload);
723

    
724
		if ($g['booting'])
725
			echo "done.\n";
726
	}
727

    
728
	/* set up BRIDGe virtual interfaces */
729
	interfaces_bridge_configure();
730

    
731
	foreach ($bridge_list as $if => $ifname) {
732
		if ($g['booting'])
733
			echo "Configuring {$ifname} interface...";
734
		if($g['debug'])
735
			log_error("Configuring {$ifname}");
736

    
737
		interface_configure($if, $reload);
738

    
739
		if ($g['booting'])
740
			echo "done.\n";
741
	}
742

    
743
	/* bring up vip interfaces */
744
	interfaces_vips_configure();
745

    
746
	/* configure interface groups */
747
	interfaces_group_setup();
748

    
749
	if (!$g['booting']) {
750
		/* reconfigure static routes (kernel may have deleted them) */
751
		system_routing_configure();
752

    
753
		/* reload IPsec tunnels */
754
		vpn_ipsec_configure();
755

    
756
		/* reload dhcpd (interface enabled/disabled status may have changed) */
757
		services_dhcpd_configure();
758

    
759
		/* restart dnsmasq */
760
		services_dnsmasq_configure();
761

    
762
		/* reload captive portal */
763
		captiveportal_init_rules();
764

    
765
		/* set the reload filter dity flag */
766
		filter_configure();
767
	}
768

    
769
	return 0;
770
}
771

    
772
function interface_reconfigure($interface = "wan") {
773
	interface_bring_down($interface);
774
	interface_configure($interface, true);
775
}
776

    
777
function interface_vip_bring_down(&$vip) {
778
	global $g;
779

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

    
804
function interface_bring_down($interface = "wan", $destroy = false) {
805
	global $config, $g;
806

    
807
	if (!isset($config['interfaces'][$interface]))
808
		return; 
809

    
810
	$ifcfg = $config['interfaces'][$interface];
811

    
812
	$realif = get_real_interface($interface);
813

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

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

    
870
	if ($destroy == true) {
871
		if (preg_match("/^vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
872
			pfSense_interface_destroy($realif);
873
	}	
874

    
875
	return;
876
}
877

    
878
function interfaces_ptpid_used($ptpid) {
879
	global $config;
880

    
881
	if (is_array($config['ppps']['ppp']))
882
		foreach ($config['ppps']['ppp'] as & $settings)
883
			if ($ptpid == $settings['ptpid'])
884
				return true;
885

    
886
	return false;
887
}
888

    
889
function interfaces_ptpid_next() {
890

    
891
	$ptpid = 0;
892
	while(interfaces_ptpid_used($ptpid))
893
		$ptpid++;
894

    
895
	return $ptpid;
896
}
897

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

    
912
function handle_pppoe_reset($post_array) {
913
	global $config, $g;
914

    
915
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
916

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

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

    
999
/*	This function can configure PPPoE, MLPPP (PPPoE), PPtP.
1000
*	It writes the mpd config file to /var/etc every time the link is opened.
1001
*/
1002

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

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

    
1121
		if (is_ipaddr($ppp['gateway']))
1122
			$gateway = $ppp['gateway'];
1123
		else
1124
			$gateway = "10.64.64.{$pppid}";
1125
		$ranges = "{$localip}/0 {$gateway}/0";
1126
		
1127
		if (empty($ppp['apnum']))	
1128
			$ppp['apnum'] = 1;
1129
	} else
1130
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1131

    
1132
	if (isset($ppp['ondemand'])) 
1133
		$ondemand = "enable";
1134
	else
1135
		$ondemand = "disable";
1136
	if (!isset($ppp['idletimeout']))
1137
		$ppp['idletimeout'] = 0;
1138

    
1139
	if (empty($ppp['username']) && $type == "modem"){
1140
		$ppp['username'] = "user";
1141
		$ppp['password'] = "none";
1142
	}
1143
	if (empty($ppp['password']) && $type == "modem")
1144
		$passwd = "none";
1145
	else
1146
		$passwd = base64_decode($ppp['password']);
1147

    
1148
	$bandwidths = explode(',',$ppp['bandwidth']);
1149
	$mtus = explode(',',$ppp['mtu']);
1150
	$mrus = explode(',',$ppp['mru']);
1151

    
1152
	if (isset($ppp['mrru']))
1153
		$mrrus = explode(',',$ppp['mrru']);
1154

    
1155
	// Construct the mpd.conf file
1156
	$mpdconf = <<<EOD
1157
startup:
1158
	# configure the console
1159
	set console close
1160
	# configure the web server
1161
	set web close
1162

    
1163
default:
1164
{$ppp['type']}client:
1165
	create bundle static {$interface}
1166
	set iface name {$pppif}
1167

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

    
1188
EOD;
1189
	}
1190
	$mpdconf .= <<<EOD
1191
	set iface {$ondemand} on-demand
1192
	set iface idle {$ppp['idletimeout']}
1193

    
1194
EOD;
1195

    
1196
	if (isset($ppp['ondemand']))
1197
		$mpdconf .= <<<EOD
1198
	set iface addrs 10.10.1.1 10.10.1.2
1199

    
1200
EOD;
1201
	
1202
	if (isset($ppp['tcpmssfix']))
1203
		$tcpmss = "disable";
1204
	else
1205
		$tcpmss = "enable";
1206
		$mpdconf .= <<<EOD
1207
	set iface {$tcpmss} tcpmssfix
1208

    
1209
EOD;
1210

    
1211
	$mpdconf .= <<<EOD
1212
	set iface up-script /usr/local/sbin/ppp-linkup
1213
	set iface down-script /usr/local/sbin/ppp-linkdown
1214
	set ipcp ranges {$ranges}
1215

    
1216
EOD;
1217
	if (isset($ppp['vjcomp']))
1218
		$mpdconf .= <<<EOD
1219
	set ipcp no vjcomp
1220

    
1221
EOD;
1222

    
1223
	if (isset($config['system']['dnsallowoverride']))
1224
		$mpdconf .= <<<EOD
1225
	set ipcp enable req-pri-dns
1226
	set ipcp enable req-sec-dns
1227

    
1228
EOD;
1229
	if (!isset($ppp['verbose_log']))
1230
		$mpdconf .= <<<EOD
1231
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1232

    
1233
EOD;
1234
	foreach($ports as $pid => $port){
1235
		$port = get_real_interface($port);
1236
		$mpdconf .= <<<EOD
1237

    
1238
	create link static {$interface}_link{$pid} {$type}
1239
	set link action bundle {$interface}
1240
	set link {$multilink} multilink
1241
	set link keep-alive 10 60
1242
	set link max-redial 0
1243

    
1244
EOD;
1245
		if (isset($ppp['shortseq']))
1246
			$mpdconf .= <<<EOD
1247
	set link no shortseq
1248

    
1249
EOD;
1250

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

    
1255
EOD;
1256

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

    
1261
EOD;
1262

    
1263
		$mpdconf .= <<<EOD
1264
	set link disable chap pap
1265
	set link accept chap pap eap
1266
	set link disable incoming
1267

    
1268
EOD;
1269

    
1270

    
1271
		if (!empty($bandwidths[$pid]))
1272
			$mpdconf .= <<<EOD
1273
	set link bandwidth {$bandwidths[$pid]}
1274

    
1275
EOD;
1276

    
1277
		if (empty($mtus[$pid]))
1278
			$mtus[$pid] = "1492";
1279
			$mpdconf .= <<<EOD
1280
	set link mtu {$mtus[$pid]}
1281

    
1282
EOD;
1283

    
1284
		if (!empty($mrus[$pid]))
1285
			$mpdconf .= <<<EOD
1286
	set link mru {$mrus[$pid]}
1287

    
1288
EOD;
1289

    
1290
		$mpdconf .= <<<EOD
1291
	set auth authname "{$ppp['username']}"
1292
	set auth password {$passwd}
1293

    
1294
EOD;
1295
		if ($type == "modem") {
1296
			$mpdconf .= <<<EOD
1297
	set modem device {$ppp['ports']}
1298
	set modem script DialPeer
1299
	set modem idle-script Ringback
1300
	set modem watch -cd
1301
	set modem var \$DialPrefix "DT"
1302
	set modem var \$Telephone "{$ppp['phone']}"
1303

    
1304
EOD;
1305
		}
1306
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1307
			$mpdconf .= <<<EOD
1308
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1309

    
1310
EOD;
1311
		}
1312
		if (isset($ppp['initstr']) && $type == "modem") {
1313
			$initstr = base64_decode($ppp['initstr']);
1314
			$mpdconf .= <<<EOD
1315
	set modem var \$InitString "{$initstr}"
1316

    
1317
EOD;
1318
		}
1319
		if (isset($ppp['simpin']) && $type == "modem") {
1320
			$mpdconf .= <<<EOD
1321
	set modem var \$SimPin "{$ppp['simpin']}"
1322
	set modem var \$PinWait "{$ppp['pin-wait']}"
1323

    
1324
EOD;
1325
		}
1326
		if (isset($ppp['apn']) && $type == "modem") {
1327
			$mpdconf .= <<<EOD
1328
	set modem var \$APN "{$ppp['apn']}"
1329
	set modem var \$APNum "{$ppp['apnum']}"
1330

    
1331
EOD;
1332
		}
1333
		if (isset($ppp['provider']) && $type == "pppoe") {
1334
			$mpdconf .= <<<EOD
1335
	set pppoe service "{$ppp['provider']}"
1336

    
1337
EOD;
1338
		}
1339
		if ($type == "pppoe")
1340
			$mpdconf .= <<<EOD
1341
	set pppoe iface {$port}
1342

    
1343
EOD;
1344

    
1345
		if ($type == "pptp" || $type == "l2tp") {
1346
			$mpdconf .= <<<EOD
1347
	set pptp self {$localips[$pid]}
1348
	set pptp peer {$gateways[$pid]}
1349
	set pptp disable windowing
1350

    
1351
EOD;
1352
		}
1353
		
1354
		$mpdconf .= "\topen\r\n";
1355
	} //end foreach($port)
1356

    
1357
	// Write out mpd_ppp.conf
1358
	fwrite($fd, $mpdconf);
1359
	fclose($fd);
1360

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

    
1379
	// Check for PPPoE periodic reset request 
1380
	if ($type == "pppoe") {
1381
		if (isset($ppp['pppoe-reset-type']))
1382
			setup_pppoe_reset_file($ppp['if'], $interface);
1383
		else
1384
			setup_pppoe_reset_file($ppp['if']);
1385
	}
1386

    
1387
	return 1;
1388
}
1389

    
1390
function interfaces_carp_setup() {
1391
	global $g, $config;
1392

    
1393
	$balanacing = "";
1394
	$pfsyncinterface = "";
1395
	$pfsyncenabled = "";
1396
	if(isset($config['system']['developerspew'])) {
1397
		$mt = microtime();
1398
		echo "interfaces_carp_setup() being called $mt\n";
1399
	}
1400

    
1401
	// Prepare CmdCHAIN that will be used to execute commands.
1402
	$cmdchain = new CmdCHAIN();	
1403

    
1404
	if ($g['booting']) {
1405
		echo "Configuring CARP settings...";
1406
		mute_kernel_msgs();
1407
	}
1408

    
1409
	/* suck in configuration items */
1410
	if($config['installedpackages']['carpsettings']) {
1411
		if($config['installedpackages']['carpsettings']['config']) {
1412
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1413
				$pfsyncenabled = $carp['pfsyncenabled'];
1414
				$balanacing = $carp['balancing'];
1415
				$pfsyncinterface = $carp['pfsyncinterface'];
1416
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1417
			}
1418
		}
1419
	} else {
1420
		unset($pfsyncinterface);
1421
		unset($balanacing);
1422
		unset($pfsyncenabled);
1423
	}
1424

    
1425
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1426
	if($balanacing) {
1427
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1428
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1429
	} else
1430
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1431

    
1432
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=2", true);
1433
	if (!empty($pfsyncinterface))
1434
		$carp_sync_int = get_real_interface($pfsyncinterface);
1435

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

    
1451
	/* setup pfsync interface */
1452
	if($carp_sync_int and $pfsyncenabled) {
1453
		if (is_ipaddr($pfsyncpeerip))
1454
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1455
		else
1456
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1457
	} else
1458
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1459

    
1460
	if($config['virtualip']['vip'])
1461
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1462
	else
1463
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1464
	
1465
	if($g['debug'])
1466
		$cmdchain->setdebug(); // optional for verbose logging
1467

    
1468
	$cmdchain->execute();
1469
	$cmdchain->clear();
1470

    
1471
	if ($g['booting']) {
1472
		unmute_kernel_msgs();
1473
		echo "done.\n";
1474
	}
1475
}
1476

    
1477
function interface_proxyarp_configure($interface = "") {
1478
	global $config, $g;
1479
	if(isset($config['system']['developerspew'])) {
1480
		$mt = microtime();
1481
		echo "interface_proxyarp_configure() being called $mt\n";
1482
	}
1483

    
1484
	/* kill any running choparp */
1485
	if (empty($interface))
1486
		killbyname("choparp");
1487

    
1488
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1489
		$paa = array();
1490

    
1491
		/* group by interface */
1492
		foreach ($config['virtualip']['vip'] as $vipent) {
1493
			if ($vipent['mode'] === "proxyarp") {
1494
				if ($vipent['interface'])
1495
					$proxyif = $vipent['interface'];
1496
				else
1497
					$proxyif = "wan";
1498

    
1499
				if (!is_array($paa[$if]))
1500
					$paa[$proxyif] = array();
1501

    
1502
				$paa[$proxyif][] = $vipent;
1503
			}
1504
		}
1505
	}
1506

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

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

    
1583
function interface_ipalias_configure(&$vip) {
1584

    
1585
	if ($vip['mode'] == "ipalias") {
1586
		$if = get_real_interface($vip['interface']);
1587
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1588
	}
1589
}
1590

    
1591
function interface_reload_carps($cif) {
1592
	global $config;
1593

    
1594
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1595
	if (empty($carpifs))
1596
		return;
1597

    
1598
	$carps = explode(" ", $carpifs);
1599
	if(is_array($config['virtualip']['vip'])) {
1600
		$viparr = &$config['virtualip']['vip'];
1601
		foreach ($viparr as $vip) {
1602
			if (in_array($vip['carpif'], $carps)) {
1603
				switch ($vip['mode']) {
1604
					case "carp":
1605
					interface_vip_bring_down($vip);
1606
					sleep(1);
1607
					interface_carp_configure($vip);
1608
					break;
1609
					case "carpdev-dhcp":
1610
					interface_vip_bring_down($vip);
1611
					sleep(1);
1612
					interface_carpdev_configure($vip);
1613
					break;
1614
				}
1615
			}
1616
		}
1617
	}
1618
}
1619

    
1620
function interface_carp_configure(&$vip) {
1621
	global $config, $g;
1622
	if(isset($config['system']['developerspew'])) {
1623
		$mt = microtime();
1624
		echo "interface_carp_configure() being called $mt\n";
1625
	}
1626

    
1627
	if ($vip['mode'] != "carp")
1628
		return;
1629

    
1630
	$vip_password = $vip['password'];
1631
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1632
	if ($vip['password'] != "")
1633
		$password = " pass {$vip_password}";
1634

    
1635
	// set the vip interface to the vhid
1636
	$vipif = "vip{$vip['vhid']}";
1637

    
1638
	$interface = interface_translate_type_to_real($vip['interface']);
1639
	/*
1640
	 * ensure the interface containing the VIP really exists
1641
 	 * prevents a panic if the interface is missing or invalid
1642
	 */
1643
	$realif = get_real_interface($vip['interface']);
1644
	if (!does_interface_exist($realif)) {
1645
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1646
		return;
1647
	}
1648

    
1649
	/* Ensure CARP IP really exists prior to loading up. */
1650
	$ww_subnet_ip = find_interface_ip($realif);
1651
	$ww_subnet_bits = find_interface_subnet($realif);
1652
	if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits)) {
1653
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1654
		return;
1655
	}
1656

    
1657
	/* create the carp interface and setup */
1658
	if (does_interface_exist($vipif)) {
1659
		pfSense_interface_flags($vipif, -IFF_UP);
1660
	} else {
1661
		$carpif = pfSense_interface_create("carp");
1662
		pfSense_interface_rename($carpif, $vipif);
1663
		pfSense_ngctl_name("{$carpif}:", $vipif);
1664
	}
1665

    
1666
	/* invalidate interface cache */
1667
	get_interface_arr(true);
1668

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

    
1672
	interfaces_bring_up($vipif);
1673
	
1674
	return $vipif;
1675
}
1676

    
1677
function interface_carpdev_configure(&$vip) {
1678
	global $g;
1679

    
1680
	if ($vip['mode'] != "carpdev-dhcp")
1681
		return;
1682

    
1683
	$vip_password = $vip['password'];
1684
	$vip_password = str_replace(" ", "", $vip_password);
1685
	if($vip['password'] != "")
1686
		$password = " pass \"" . $vip_password . "\"";
1687

    
1688
	log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1689
	if (empty($vip['interface']))
1690
		return;
1691

    
1692
	$vipif = "vip" . $vip['vhid'];
1693
	$realif = interface_translate_type_to_real($vip['interface']);
1694
	interfaces_bring_up($realif);
1695
	/*
1696
	 * ensure the interface containing the VIP really exists
1697
	 * prevents a panic if the interface is missing or invalid
1698
	 */
1699
	if (!does_interface_exist($realif)) {
1700
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1701
		return;
1702
	}
1703

    
1704
	if (does_interface_exist($vipif)) {
1705
		interface_bring_down($vipif);
1706
	} else {
1707
		$carpdevif = exec("/sbin/ifconfig carp create");
1708
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1709
		pfSense_ngctl_name("{$carpdevif}:", $vipif);
1710
	}
1711

    
1712
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1713
	interfaces_bring_up($vipif);
1714

    
1715
	/*
1716
	 * XXX: BIG HACK but carpdev needs ip services active
1717
	 *      before even starting something as dhclient.
1718
	 *      I do not know if this is a feature or a bug
1719
	 *      but better than track it make it work ;) .
1720
	 */
1721
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1722
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1723

    
1724
	/* generate dhclient_wan.conf */
1725
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1726
	if ($fd) {
1727
		$dhclientconf = "";
1728

    
1729
		$dhclientconf .= <<<EOD
1730
interface "{$vipif}" {
1731
timeout 60;
1732
retry 1;
1733
select-timeout 0;
1734
initial-interval 1;
1735
script "/sbin/dhclient-script";
1736
}
1737

    
1738
EOD;
1739

    
1740
		fwrite($fd, $dhclientconf);
1741
		fclose($fd);
1742

    
1743
		/* fire up dhclient */
1744
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} > {$g['tmp_path']}/{$vipif}_output > {$g['tmp_path']}/{$vipif}_error_output", false);
1745
	} else {
1746
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1747
		mwexec("/sbin/dhclient -b {$vipif}");
1748
	}
1749

    
1750
	return $vipif;
1751
}
1752

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

    
1794
	if($needs_clone == true) {
1795
		/* remove previous instance if it exists */
1796
		if(does_interface_exist($realif))
1797
			pfSense_interface_destroy($realif);
1798

    
1799
		log_error("Cloning new wireless interface {$realif}");
1800
		// Create the new wlan interface. FreeBSD returns the new interface name.
1801
		// example:  wlan2
1802
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1803
		if($ret <> 0) {
1804
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1805
			return false;
1806
		}
1807
		$newif = trim($out[0]);
1808
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1809
		pfSense_interface_rename($newif, $realif);
1810
		// FIXME: not sure what ngctl is for. Doesn't work.
1811
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1812
	}
1813
	return true;
1814
}
1815

    
1816
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1817
	global $config, $g;
1818

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

    
1821
	if(!is_interface_wireless($ifcfg['if']))
1822
		return;
1823

    
1824
	$baseif = interface_get_wireless_base($ifcfg['if']);
1825

    
1826
	$iflist = get_configured_interface_list(false, true);
1827
	foreach ($iflist as $if) {
1828
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
1829
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
1830
				foreach ($shared_settings as $setting) {
1831
					if ($sync_changes) {
1832
						$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
1833
					} else {
1834
						$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
1835
					}
1836
				}
1837
				if (!$sync_changes)
1838
					break;
1839
			}
1840
		}
1841
	}
1842

    
1843
	if (interface_is_wireless_clone($ifcfg['if'])) {
1844
		foreach ($config['wireless']['clone'] as &$clone) {
1845
			if ($clone['cloneif'] == $ifcfg['if']) {
1846
				if ($sync_changes) {
1847
					$clone['mode'] = $ifcfg['wireless']['mode'];
1848
				} else {
1849
					$ifcfg['wireless']['mode'] = $clone['mode'];
1850
				}
1851
				break;
1852
			}
1853
		}
1854
		unset($clone);
1855
	}
1856
}
1857

    
1858
function interface_wireless_configure($if, &$wl, &$wlcfg) {
1859
	global $config, $g;
1860

    
1861
	/*    open up a shell script that will be used to output the commands.
1862
	 *    since wireless is changing a lot, these series of commands are fragile
1863
     *    and will sometimes need to be verified by a operator by executing the command
1864
     *    and returning the output of the command to the developers for inspection.  please
1865
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1866
	 */
1867

    
1868
	// Remove script file
1869
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1870

    
1871
	// Clone wireless nic if needed.
1872
	interface_wireless_clone($if, $wl);
1873

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

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

    
1881
	/* set values for /path/program */
1882
	$hostapd = "/usr/sbin/hostapd";
1883
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1884
	$ifconfig = "/sbin/ifconfig";
1885
	$killall = "/usr/bin/killall";
1886

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

    
1889
	$wlcmd = array();
1890
	/* Make sure it's up */
1891
	$wlcmd[] = "up";
1892
	/* Set a/b/g standard */
1893
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
1894
	$wlcmd[] = "mode " . escapeshellarg($standard);
1895

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

    
1901
	/* Set ssid */
1902
	if($wlcfg['ssid'])
1903
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
1904

    
1905
	/* Set 802.11g protection mode */
1906
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
1907

    
1908
	/* set wireless channel value */
1909
	if(isset($wlcfg['channel'])) {
1910
		if($wlcfg['channel'] == "0") {
1911
			$wlcmd[] = "channel any";
1912
		} else {
1913
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
1914
		}
1915
	}
1916

    
1917
	/* set Distance value */
1918
	if($wlcfg['distance'])
1919
		$distance = escapeshellarg($wlcfg['distance']);
1920

    
1921
	/* Set wireless hostap mode */
1922
	if ($wlcfg['mode'] == "hostap") {
1923
		$wlcmd[] = "mediaopt hostap";
1924
	} else {
1925
		$wlcmd[] = "-mediaopt hostap";
1926
	}
1927

    
1928
	/* Set wireless adhoc mode */
1929
	if ($wlcfg['mode'] == "adhoc") {
1930
		$wlcmd[] = "mediaopt adhoc";
1931
	} else {
1932
		$wlcmd[] = "-mediaopt adhoc";
1933
	}
1934

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

    
1937
	/* handle hide ssid option */
1938
	if(isset($wlcfg['hidessid']['enable'])) {
1939
		$wlcmd[] = "hidessid";
1940
	} else {
1941
		$wlcmd[] = "-hidessid";
1942
	}
1943

    
1944
	/* handle pureg (802.11g) only option */
1945
	if(isset($wlcfg['pureg']['enable'])) {
1946
		$wlcmd[] = "mode 11g pureg";
1947
	} else {
1948
		$wlcmd[] = "-pureg";
1949
	}
1950

    
1951
	/* handle puren (802.11n) only option */
1952
	if(isset($wlcfg['puren']['enable'])) {
1953
		$wlcmd[] = "puren";
1954
	} else {
1955
		$wlcmd[] = "-puren";
1956
	}
1957

    
1958
	/* enable apbridge option */
1959
	if(isset($wlcfg['apbridge']['enable'])) {
1960
		$wlcmd[] = "apbridge";
1961
	} else {
1962
		$wlcmd[] = "-apbridge";
1963
	}
1964

    
1965
	/* handle turbo option */
1966
	if(isset($wlcfg['turbo']['enable'])) {
1967
		$wlcmd[] = "mediaopt turbo";
1968
	} else {
1969
		$wlcmd[] = "-mediaopt turbo";
1970
	}
1971

    
1972
	/* handle txpower setting */
1973
	/* if($wlcfg['txpower'] <> "")
1974
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
1975
	*/
1976
	/* handle wme option */
1977
	if(isset($wlcfg['wme']['enable'])) {
1978
		$wlcmd[] = "wme";
1979
	} else {
1980
		$wlcmd[] = "-wme";
1981
	}
1982

    
1983
	/* set up wep if enabled */
1984
	$wepset = "";
1985
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
1986
		switch($wlcfg['wpa']['auth_algs']) {
1987
			case "1":
1988
				$wepset .= "authmode open wepmode on ";
1989
				break;
1990
			case "2":
1991
				$wepset .= "authmode shared wepmode on ";
1992
				break;
1993
			case "3":
1994
				$wepset .= "authmode mixed wepmode on ";
1995
		}
1996
		$i = 1;
1997
		foreach ($wlcfg['wep']['key'] as $wepkey) {
1998
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
1999
			if (isset($wepkey['txkey'])) {
2000
				$wlcmd[] = "weptxkey {$i} ";
2001
			}
2002
			$i++;
2003
		}
2004
		$wlcmd[] = $wepset;
2005
	} else {
2006
		$wlcmd[] = "authmode open wepmode off ";
2007
	}
2008

    
2009
	mwexec(kill_hostapd("{$if}"));
2010
	mwexec(kill_wpasupplicant("{$if}"));
2011

    
2012
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2013
	conf_mount_rw();
2014

    
2015
	switch ($wlcfg['mode']) {
2016
		case 'bss':
2017
			if (isset($wlcfg['wpa']['enable'])) {
2018
				$wpa .= <<<EOD
2019
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2020
ctrl_interface_group=0
2021
ap_scan=1
2022
#fast_reauth=1
2023
network={
2024
ssid="{$wlcfg['ssid']}"
2025
scan_ssid=1
2026
priority=5
2027
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2028
psk="{$wlcfg['wpa']['passphrase']}"
2029
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2030
group={$wlcfg['wpa']['wpa_pairwise']}
2031
}
2032
EOD;
2033

    
2034
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2035
				fwrite($fd, "{$wpa}");
2036
				fclose($fd);
2037
			}
2038
			break;
2039
		case 'hostap':
2040
			if($wlcfg['wpa']['passphrase']) 
2041
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2042
			else 
2043
				$wpa_passphrase = "";
2044
			if (isset($wlcfg['wpa']['enable'])) {
2045
				$wpa .= <<<EOD
2046
interface={$if}
2047
driver=bsd
2048
logger_syslog=-1
2049
logger_syslog_level=0
2050
logger_stdout=-1
2051
logger_stdout_level=0
2052
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2053
ctrl_interface={$g['varrun_path']}/hostapd
2054
ctrl_interface_group=wheel
2055
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2056
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2057
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2058
ssid={$wlcfg['ssid']}
2059
debug={$wlcfg['wpa']['debug_mode']}
2060
auth_algs={$wlcfg['wpa']['auth_algs']}
2061
wpa={$wlcfg['wpa']['wpa_mode']}
2062
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2063
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2064
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2065
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2066
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2067
{$wpa_passphrase}
2068
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2069
#rsn_preauth=1
2070
#rsn_preauth_interfaces=eth0
2071

    
2072
EOD;
2073

    
2074
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2075
					$auth_server_port = "1812";
2076
					if($wlcfg['auth_server_port']) 
2077
						$auth_server_port = $wlcfg['auth_server_port'];
2078
					$wpa .= <<<EOD
2079

    
2080
ieee8021x=1
2081
auth_server_addr={$wlcfg['auth_server_addr']}
2082
auth_server_port={$auth_server_port}
2083
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2084

    
2085
EOD;
2086
				} else {
2087
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2088
				}
2089

    
2090
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2091
				fwrite($fd, "{$wpa}");
2092
				fclose($fd);
2093

    
2094
			}
2095
			break;
2096
	}
2097

    
2098
	/*
2099
	 *    all variables are set, lets start up everything
2100
	 */
2101

    
2102
	$baseif = interface_get_wireless_base($if);
2103

    
2104
	/* set ack timers according to users preference (if he/she has any) */
2105
	if($distance) {
2106
		fwrite($fd_set, "# Enable ATH distance settings\n");
2107
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2108
	}
2109

    
2110
	if (isset($wlcfg['wpa']['enable'])) {
2111
		if ($wlcfg['mode'] == "bss") {
2112
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2113
		}
2114
		if ($wlcfg['mode'] == "hostap") {
2115
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
2116
		}
2117
	}
2118

    
2119
	fclose($fd_set);
2120
	conf_mount_ro();
2121

    
2122
	/* Making sure regulatory settings have actually changed
2123
	 * before applying, because changing them requires bringing
2124
	 * down all wireless networks on the interface. */
2125
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2126
	$ifconfig_str = implode($output);
2127
	unset($output);
2128
	$reg_changing = false;
2129

    
2130
	if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2131
		$reg_changing = true;
2132
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2133
		$reg_changing = true;
2134
	/* anywhere needs a special case, since it is not included in the ifconfig output.
2135
	 * Do not combine this if with the one inside. */
2136
	else if ($wlcfg['reglocation'] == 'anywhere') {
2137
		if (preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2138
			$reg_changing = true;
2139
	} else if ($wlcfg['reglocation'] && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2140
		$reg_changing = true;
2141

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

    
2146
	if ($reg_changing) {
2147
		/* set regulatory domain */
2148
		if($wlcfg['regdomain'])
2149
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2150

    
2151
		/* set country */
2152
		if($wlcfg['regcountry'])
2153
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2154

    
2155
		/* set location */
2156
		if($wlcfg['reglocation'])
2157
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2158

    
2159
		$wlregcmd_args = implode(" ", $wlregcmd);
2160

    
2161
		/* build a complete list of the wireless clones for this interface */
2162
		$clone_list = array();
2163
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2164
			$clone_list[] = interface_get_wireless_clone($baseif);
2165
		if (is_array($config['wireless']['clone'])) {
2166
			foreach ($config['wireless']['clone'] as $clone) {
2167
				if ($clone['if'] == $baseif)
2168
					$clone_list[] = $clone['cloneif'];
2169
			}
2170
		}
2171

    
2172
		/* find which clones are up and bring them down */
2173
		$clones_up = array();
2174
		foreach ($clone_list as $clone_if) {
2175
			$clone_status = pfSense_get_interface_addresses($clone_if);
2176
			if ($clone_status['status'] == 'up') {
2177
				$clones_up[] = $clone_if;
2178
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2179
			}
2180
		}
2181

    
2182
		/* apply the regulatory settings */
2183
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2184

    
2185
		/* bring the clones back up that were previously up */
2186
		foreach ($clones_up as $clone_if) {
2187
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2188
		}
2189
	}
2190

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

    
2195
	/* configure wireless */
2196
	$wlcmd_args = implode(" ", $wlcmd);
2197
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2198

    
2199
	
2200
	sleep(1);
2201
	/* execute hostapd and wpa_supplicant if required in shell */
2202
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2203

    
2204
	return 0;
2205

    
2206
}
2207

    
2208
function kill_hostapd($interface) {
2209
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2210
}
2211

    
2212
function kill_wpasupplicant($interface) {
2213
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2214
}
2215

    
2216
function find_dhclient_process($interface) {
2217
	if($interface) {
2218
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
2219
	}
2220
	return $pid;
2221
}
2222

    
2223
function interface_configure($interface = "wan", $reloadall = false) {
2224
	global $config, $g;
2225
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2226

    
2227
	$wancfg = $config['interfaces'][$interface];
2228

    
2229
	$realif = get_real_interface($interface);
2230

    
2231
	if (!$g['booting']) {
2232
		/* remove all IPv4 addresses */
2233
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2234
			interface_bring_down($interface);
2235
	}
2236

    
2237
	/* wireless configuration? */
2238
	if (is_array($wancfg['wireless']))
2239
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2240

    
2241
	if ($wancfg['spoofmac']) {
2242
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
2243
			" link " . escapeshellarg($wancfg['spoofmac']));
2244

    
2245
                /*
2246
                 * All vlans need to spoof their parent mac address, too.  see
2247
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2248
                 */
2249
                if (is_array($config['vlans']['vlan'])) {
2250
                        foreach ($config['vlans']['vlan'] as $vlan) {
2251
                                if ($vlan['if'] == $realif)
2252
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2253
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2254
                        }
2255
                }
2256
	}  else {
2257
		$mac = get_interface_mac(get_real_interface($wancfg['if']));
2258
		if($mac == "ff:ff:ff:ff:ff:ff") {
2259
			/*   this is not a valid mac address.  generate a
2260
			 *   temporary mac address so the machine can get online.
2261
			 */
2262
			echo "Generating new MAC address.";
2263
			$random_mac = generate_random_mac_address();
2264
			mwexec("/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if'])) .
2265
				" link " . escapeshellarg($random_mac));
2266
			$wancfg['spoofmac'] = $random_mac;
2267
			write_config();
2268
			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");
2269
		}
2270
	}
2271

    
2272
	/* media */
2273
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2274
		$cmd = "/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if']));
2275
		if ($wancfg['media'])
2276
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2277
		if ($wancfg['mediaopt'])
2278
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2279
		mwexec($cmd);
2280
	}
2281
	if (!empty($wancfg['mtu']))
2282
		pfSense_interface_mtu($realif, $wancfg['mtu']);
2283

    
2284
	/* invalidate interface/ip/sn cache */
2285
	get_interface_arr(true);
2286
	unset($interface_ip_arr_cache[$realif]);
2287
	unset($interface_sn_arr_cache[$realif]);
2288

    
2289
	switch ($wancfg['ipaddr']) {
2290
		case 'carpdev-dhcp':
2291
			interface_carpdev_dhcp_configure($interface);
2292
			break;
2293
		case 'dhcp':
2294
			interface_dhcp_configure($interface);
2295
			break;
2296
		case 'pppoe':
2297
		case 'l2tp':
2298
		case 'pptp':
2299
		case 'ppp':
2300
			interface_ppps_configure($interface);
2301
			break;
2302
		default:
2303
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
2304
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2305
			} else if (substr($realif, 0, 3) == "gre") {
2306
				if (is_array($config['gres']['gre'])) {
2307
					foreach ($config['gres']['gre'] as $gre)
2308
						if ($gre['greif'] == $realif)
2309
							interface_gre_configure($gre);
2310
				}
2311
			} else if (substr($realif, 0, 3) == "gif") {
2312
				 if (is_array($config['gifs']['gif'])) {
2313
					foreach ($config['gifs']['gif'] as $gif)
2314
						if($gif['gifif'] == $interface)
2315
							interface_gif_configure($gif);
2316
				}
2317
			} else if (substr($realif, 0, 4) == "ovpn") {
2318
				/* XXX: Should be done anything?! */
2319
			}
2320

    
2321
			if (is_ipaddr($wancfg['gateway']))
2322
				file_put_contents("{$g['tmp_path']}/{$realif}_router", $wancfg['gateway']);
2323
			break;
2324
	}
2325

    
2326
	if(does_interface_exist($wancfg['if']))
2327
		interfaces_bring_up($wancfg['if']);
2328
 	
2329
	if (!$g['booting'])
2330
		interface_reload_carps($realif);
2331
	
2332
	if (!$g['booting']) {
2333
		if (link_interface_to_gre($interface)) {
2334
			foreach ($config['gres']['gre'] as $gre)
2335
				if ($gre['if'] == $interface)
2336
					interface_gre_configure($gre);
2337
		}
2338
		if (link_interface_to_gif($interface)) {
2339
                	foreach ($config['gifs']['gif'] as $gif)
2340
				if ($gif['if'] == $interface)
2341
                        		interface_gif_configure($gif);
2342
        	}
2343
		if (link_interface_to_bridge($interface)) {
2344
			foreach ($config['bridges']['bridged'] as $bridge)
2345
				if (stristr($bridge['members'], "{$interface}"))
2346
					interface_bridge_add_member($bridge['bridgeif'], $realif);
2347
		}
2348

    
2349
		link_interface_to_vips($interface, "update");
2350

    
2351
		if ($interface == "lan")
2352
			/* make new hosts file */
2353
			system_hosts_generate();
2354

    
2355
		if ($reloadall == true) {
2356

    
2357
			/* reconfigure static routes (kernel may have deleted them) */
2358
			system_routing_configure($interface);
2359

    
2360
			/* reload ipsec tunnels */
2361
			vpn_ipsec_configure();
2362

    
2363
			/* update dyndns */
2364
			services_dyndns_configure($interface);
2365

    
2366
			/* force DNS update */
2367
			services_dnsupdate_process($interface);
2368

    
2369
			/* restart dnsmasq */
2370
			services_dnsmasq_configure();
2371

    
2372
			/* reload captive portal */
2373
			captiveportal_init_rules();
2374

    
2375
			/* set the reload filter dity flag */
2376
			filter_configure();
2377
		}
2378
	}
2379

    
2380
	return 0;
2381
}
2382

    
2383
function interface_carpdev_dhcp_configure($interface = "wan") {
2384
	global $config, $g;
2385

    
2386
	$wancfg = $config['interfaces'][$interface];
2387
	$wanif = $wancfg['if'];
2388
	/* bring wan interface up before starting dhclient */
2389
	if($wanif)
2390
		interfaces_bring_up($wanif);
2391
	else 
2392
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2393

    
2394
	return 0;
2395
}
2396

    
2397
function interface_dhcp_configure($interface = "wan") {
2398
	global $config, $g;
2399

    
2400
	$wancfg = $config['interfaces'][$interface];
2401
	if (empty($wancfg))
2402
		$wancfg = array();
2403

    
2404
	/* generate dhclient_wan.conf */
2405
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2406
	if (!$fd) {
2407
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2408
		return 1;
2409
	}
2410

    
2411
	if ($wancfg['dhcphostname']) {
2412
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2413
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2414
	} else {
2415
		$dhclientconf_hostname = "";
2416
	}
2417

    
2418
	$wanif = get_real_interface($interface);
2419
	if (empty($wanif)) {
2420
		log_error("Invalid interface \"{$interface}\" in interface_dhcp_configure()");
2421
		return 0;
2422
	}
2423
 	$dhclientconf = "";
2424
	
2425
	$dhclientconf .= <<<EOD
2426
interface "{$wanif}" {
2427
timeout 60;
2428
retry 1;
2429
select-timeout 0;
2430
initial-interval 1;
2431
	{$dhclientconf_hostname}
2432
	script "/sbin/dhclient-script";
2433
}
2434

    
2435
EOD;
2436

    
2437
if(is_ipaddr($wancfg['alias-address'])) {
2438
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2439
	$dhclientconf .= <<<EOD
2440
alias {
2441
	interface  "{$wanif}";
2442
	fixed-address {$wancfg['alias-address']};
2443
	option subnet-mask {$subnetmask};
2444
}
2445

    
2446
EOD;
2447
}
2448
	fwrite($fd, $dhclientconf);
2449
	fclose($fd);
2450

    
2451
	/* bring wan interface up before starting dhclient */
2452
	if($wanif)
2453
		interfaces_bring_up($wanif);
2454
	else 
2455
		log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
2456

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

    
2460
	return 0;
2461
}
2462

    
2463
function interfaces_group_setup() {
2464
	global $config;
2465

    
2466
	if (!is_array($config['ifgroups']['ifgroupentry']))
2467
		return;
2468

    
2469
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2470
		interface_group_setup($groupar);
2471

    
2472
	return;
2473
}
2474

    
2475
function interface_group_setup(&$groupname /* The parameter is an array */) {
2476
	global $config;
2477

    
2478
	if (!is_array($groupname))
2479
		return;
2480
	$members = explode(" ", $groupname['members']);
2481
	foreach($members as $ifs) {
2482
		$realif = get_real_interface($ifs);
2483
		if ($realif)
2484
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2485
	}
2486

    
2487
	return;
2488
}
2489
 
2490
/* COMPAT Function */
2491
function convert_friendly_interface_to_real_interface_name($interface) {
2492
	return get_real_interface($interface);
2493
}
2494

    
2495
/* COMPAT Function */
2496
function get_real_wan_interface($interface = "wan") {
2497
	return get_real_interface($interface);
2498
}
2499

    
2500
/* COMPAT Function */
2501
function get_current_wan_address($interface = "wan") {
2502
	return get_interface_ip($interface);
2503
}
2504

    
2505
/*
2506
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2507
 */
2508
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2509
        global $config;
2510

    
2511
	if (stristr($interface, "vip")) {
2512
                $index = intval(substr($interface, 3));
2513
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2514
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2515
                                if ($index == $counter)
2516
                                        return $vip['interface'];
2517
                        }
2518
                }
2519
        } else if (stristr($interface, "carp")) {
2520
                $index = intval(substr($interface, 4));
2521
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2522
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2523
                                if ($index == $counter)
2524
                                        return $vip['interface'];
2525
                        }
2526
                }
2527
        }
2528

    
2529
        /* XXX: For speed reasons reference directly the interface array */
2530
	$ifdescrs = $config['interfaces'];
2531
        //$ifdescrs = get_configured_interface_list(false, true);
2532

    
2533
        foreach ($ifdescrs as $if => $ifname) {
2534
                if ($config['interfaces'][$if]['if'] == $interface)
2535
                        return $if;
2536

    
2537
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2538
                $int = interface_translate_type_to_real($if);
2539
                if ($int == $interface)
2540
                        return $ifname;
2541
        }
2542
        return NULL;
2543
}
2544

    
2545
/* attempt to resolve interface to friendly descr */
2546
function convert_friendly_interface_to_friendly_descr($interface) {
2547
        global $config;
2548

    
2549
        switch ($interface) {
2550
                case "l2tp":
2551
                                $ifdesc = "L2TP";
2552
                                break;
2553
                case "pptp":
2554
                                $ifdesc = "pptp";
2555
                                break;
2556
                case "pppoe":
2557
                                $ifdesc = "pppoe";
2558
                                break;
2559
                case "openvpn":
2560
                                $ifdesc = "OpenVPN";
2561
                                break;
2562
                case "enc0":
2563
                        case "ipsec":
2564
                                $ifdesc = "IPsec";
2565
                                break;
2566
        default:
2567
                /* if list */
2568
                $ifdescrs = get_configured_interface_with_descr(false, true);
2569
                foreach ($ifdescrs as $if => $ifname) {
2570
                                if ($if == $interface || $ifname == $interface)
2571
                                        return $ifname;
2572
                }
2573
                break;
2574
        }
2575

    
2576
        return $ifdesc;
2577
}
2578

    
2579
function convert_real_interface_to_friendly_descr($interface) {
2580
        global $config;
2581

    
2582
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2583

    
2584
        if ($ifdesc) {
2585
                $iflist = get_configured_interface_with_descr(false, true);
2586
                return $iflist[$ifdesc];
2587
        }
2588

    
2589
        return $interface;
2590
}
2591

    
2592
/*
2593
 *  interface_translate_type_to_real($interface):
2594
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2595
 */
2596
function interface_translate_type_to_real($interface) {
2597
        global $config;
2598

    
2599
        if ($config['interfaces'][$interface]['if'] <> "")
2600
                return $config['interfaces'][$interface]['if'];
2601
        else
2602
		return $interface;
2603
}
2604

    
2605
function interface_is_wireless_clone($wlif) {
2606
	if(!stristr($wlif, "_wlan")) {
2607
		return false;
2608
	} else {
2609
		return true;
2610
	}
2611
}
2612

    
2613
function interface_get_wireless_base($wlif) {
2614
	if(!stristr($wlif, "_wlan")) {
2615
		return $wlif;
2616
	} else {
2617
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2618
	}
2619
}
2620

    
2621
function interface_get_wireless_clone($wlif) {
2622
	if(!stristr($wlif, "_wlan")) {
2623
		return $wlif . "_wlan0";
2624
	} else {
2625
		return $wlif;
2626
	}
2627
}
2628

    
2629
function get_real_interface($interface = "wan") {
2630
    global $config;
2631

    
2632
	$wanif = NULL;
2633

    
2634
	switch ($interface) {
2635
	case "l2tp":
2636
		$wanif = "l2tp";
2637
		break;
2638
	case "pptp":
2639
		$wanif = "pptp";
2640
		break;
2641
	case "pppoe":
2642
		$wanif = "pppoe";
2643
		break;
2644
	case "openvpn":
2645
		$wanif = "openvpn";
2646
		break;
2647
	case "ipsec":
2648
	case "enc0":
2649
		$wanif = "enc0";
2650
		break;
2651
	case "ppp":
2652
		$wanif = "ppp";
2653
		break;
2654
	default:
2655
		// If a real interface was alread passed simply
2656
		// pass the real interface back.  This encourages
2657
		// the usage of this function in more cases so that
2658
		// we can combine logic for more flexibility.
2659
		if(does_interface_exist($interface)) {
2660
			$wanif = $interface;
2661
			break;
2662
		}
2663
		if (empty($config['interfaces'][$interface]))
2664
			break;
2665

    
2666
		$cfg =& $config['interfaces'][$interface];
2667

    
2668
		// Wireless cloned NIC support (FreeBSD 8+)
2669
		// interface name format: $parentnic_wlanparentnic#
2670
		// example: ath0_wlan0
2671
		if (is_interface_wireless($cfg['if'])) {
2672
			$wanif = interface_get_wireless_clone($cfg['if']);
2673
			break;
2674
		}
2675
		/*
2676
		if (empty($cfg['if'])) {
2677
			$wancfg = $cfg['if'];
2678
			break;
2679
		}
2680
		*/
2681

    
2682
		switch ($cfg['ipaddr']) {
2683
			case "carpdev-dhcp":
2684
				$viparr = &$config['virtualip']['vip'];
2685
				if(is_array($viparr))
2686
				foreach ($viparr as $counter => $vip) {
2687
					if ($vip['mode'] == "carpdev-dhcp") {
2688
						if($vip['interface'] == $interface) {
2689
							$wanif = "carp{$counter}";
2690
							break;
2691
						}
2692
					}
2693
				}
2694
				break;
2695
			case "pppoe": 
2696
			case "pptp": 
2697
			case "l2tp": 
2698
			case "ppp":
2699
				$wanif = $cfg['if'];
2700
				break;
2701
			default:
2702
				$wanif = $cfg['if'];
2703
				break;
2704
		}
2705
		break;
2706
	}
2707

    
2708
    return $wanif;
2709
}
2710

    
2711
/* Guess the physical interface by providing a IP address */
2712
function guess_interface_from_ip($ipaddress) {
2713
	if(! is_ipaddr($ipaddress)) {
2714
		return false;
2715
	}
2716
	/* create a route table we can search */
2717
	exec("netstat -rnW", $output, $ret);
2718
	foreach($output as $line) {
2719
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
2720
			$fields = preg_split("/[ ]+/", $line);
2721
			if(ip_in_subnet($ipaddress, $fields[0])) {
2722
				return $fields[6];
2723
			}
2724
		}
2725
	}
2726
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
2727
	if(empty($ret)) {
2728
        	return false;
2729
	}
2730
	return $ret;
2731
}
2732

    
2733
/*
2734
 * find_ip_interface($ip): return the interface where an ip is defined
2735
 */
2736
function find_ip_interface($ip)
2737
{
2738
        /* if list */
2739
        $ifdescrs = get_configured_interface_list();
2740

    
2741
        foreach ($ifdescrs as $ifdescr => $ifname) {
2742
		if ($ip == get_interface_ip($ifname)) {
2743
                	$int = get_real_interface($ifname);
2744
			return $int;
2745
		}
2746
        }
2747
        return false;
2748
}
2749

    
2750
/*
2751
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
2752
 */
2753
function find_number_of_created_carp_interfaces() {
2754
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
2755
}
2756

    
2757
function get_all_carp_interfaces() {
2758
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
2759
	return $ints;
2760
}
2761

    
2762
/*
2763
 * find_carp_interface($ip): return the carp interface where an ip is defined
2764
 */
2765
function find_carp_interface($ip) {
2766
	global $config;
2767
	if (is_array($config['virtualip']['vip'])) {
2768
		foreach ($config['virtualip']['vip'] as $vip) {
2769
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2770
				$carp_ip = get_interface_ip($vip['interface']);
2771
				$if = `ifconfig | grep '$ip' -B1 | head -n1 | cut -d: -f1`;
2772
				if ($if)
2773
					return $if;
2774
			}
2775
		}
2776
	}
2777
}
2778

    
2779
function link_carp_interface_to_parent($interface) {
2780
        global $config;
2781

    
2782
        if ($interface == "")
2783
                return;
2784

    
2785
        $carp_ip = get_interface_ip($interface);
2786
        if (!is_ipaddr($carp_ip))
2787
                return;
2788

    
2789
        /* if list */
2790
        $ifdescrs = get_configured_interface_list();
2791
        foreach ($ifdescrs as $ifdescr => $ifname) {
2792
                $interfaceip = get_interface_ip($ifname);
2793
                $subnet_bits = get_interface_subnet($ifname);
2794
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
2795
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
2796
                        return $ifname;
2797
        }
2798

    
2799
        return "";
2800
}
2801

    
2802
/****f* interfaces/link_ip_to_carp_interface
2803
 * NAME
2804
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
2805
 * INPUTS
2806
 *   $ip
2807
 * RESULT
2808
 *   $carp_ints
2809
 ******/
2810
function link_ip_to_carp_interface($ip) {
2811
        global $config;
2812

    
2813
        if (!is_ipaddr($ip))
2814
                return;
2815

    
2816
        $carp_ints = "";
2817
        if (is_array($config['virtualip']['vip'])) {
2818
		$first = 0;
2819
		$carp_int = array();
2820
                foreach ($config['virtualip']['vip'] as $vip) {
2821
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2822
                                $carp_ip = $vip['subnet'];
2823
                                $carp_sn = $vip['subnet_bits'];
2824
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
2825
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
2826
					$carp_int[] = "vip{$vip['vhid']}";
2827
                        }
2828
                }
2829
		if (!empty($carp_int))
2830
			$carp_ints = implode(" ", array_unique($carp_int));
2831
        }
2832

    
2833
        return $carp_ints;
2834
}
2835

    
2836
function link_interface_to_vlans($int, $action = "") {
2837
	global $config;
2838

    
2839
	if (empty($int))
2840
		return;
2841

    
2842
	if (is_array($config['vlans']['vlan'])) {
2843
                foreach ($config['vlans']['vlan'] as $vlan) {
2844
			if ($int == $vlan['if']) {
2845
				if ($action == "update") {
2846
					interfaces_bring_up($int);
2847
				} else if ($action == "")
2848
					return $vlan;
2849
			}
2850
		}
2851
	}
2852
}
2853

    
2854
function link_interface_to_vips($int, $action = "") {
2855
        global $config;
2856

    
2857
        if (is_array($config['virtualip']['vip']))
2858
                foreach ($config['virtualip']['vip'] as $vip)
2859
                        if ($int == $vip['interface']) {
2860
				if ($action == "update")
2861
					interfaces_vips_configure($int);
2862
				else
2863
                                	return $vip;
2864
			}
2865
}
2866

    
2867
/****f* interfaces/link_interface_to_bridge
2868
 * NAME
2869
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2870
 * INPUTS
2871
 *   $ip
2872
 * RESULT
2873
 *   bridge[0-99]
2874
 ******/
2875
function link_interface_to_bridge($int) {
2876
        global $config;
2877

    
2878
        if (is_array($config['bridges']['bridged']))
2879
                foreach ($config['bridges']['bridged'] as $bridge)
2880
                        if(stristr($bridge['members'], "{$int}"))
2881
                                return "{$bridge['bridgeif']}";
2882
}
2883

    
2884
function link_interface_to_gre($interface) {
2885
        global $config;
2886

    
2887
        if (is_array($config['gres']['gre']))
2888
                foreach ($config['gres']['gre'] as $gre)
2889
                        if($gre['if'] == $interface)
2890
                                return "{$gre['greif']}";
2891
}
2892

    
2893
function link_interface_to_gif($interface) {
2894
        global $config;
2895

    
2896
        if (is_array($config['gifs']['gif']))
2897
                foreach ($config['gifs']['gif'] as $gif)
2898
                        if($gif['if'] == $interface)
2899
                                return "{$gif['gifif']}";
2900
}
2901

    
2902
/*
2903
 * find_interface_ip($interface): return the interface ip (first found)
2904
 */
2905
function find_interface_ip($interface, $flush = false)
2906
{
2907
	global $interface_ip_arr_cache;
2908

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

    
2914
	/* Setup IP cache */
2915
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2916
		$ifinfo = pfSense_get_interface_addresses($interface);
2917
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
2918
	}
2919

    
2920
	return $interface_ip_arr_cache[$interface];
2921
}
2922

    
2923
function find_interface_subnet($interface, $flush = false)
2924
{
2925
	global $interface_sn_arr_cache;
2926

    
2927
	$interface = str_replace("\n", "", $interface);
2928
	if (does_interface_exist($interface) == false)
2929
		return;
2930

    
2931
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2932
		$ifinfo = pfSense_get_interface_addresses($interface);
2933
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
2934
        }
2935

    
2936
	return $interface_sn_arr_cache[$interface];
2937
}
2938

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

    
2951
	$curip = find_interface_ip($realif);
2952
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2953
		return $curip;
2954
	else
2955
		return null;
2956
}
2957

    
2958
function get_interface_subnet($interface = "wan")
2959
{
2960
	$realif = get_real_interface($interface);
2961
	if (!$realif) {
2962
                if (preg_match("/^carp/i", $interface))
2963
                        $realif = $interface;
2964
                else if (preg_match("/^vip/i", $interface))
2965
                        $realif = $interface;
2966
                else
2967
                        return null;
2968
        }
2969

    
2970
	$cursn = find_interface_subnet($realif);
2971
	if (!empty($cursn))
2972
		return $cursn;
2973

    
2974
	return null;
2975
}
2976

    
2977
/* return outside interfaces with a gateway */
2978
function get_interfaces_with_gateway() {
2979
	global $config;
2980

    
2981
	$ints = array();
2982

    
2983
	/* loop interfaces, check config for outbound */
2984
	foreach($config['interfaces'] as $ifdescr => $ifname) {
2985

    
2986
		switch ($ifname['ipaddr']) {
2987
			case "dhcp":
2988
			case "carpdev-dhcp":
2989
			case "ppp";
2990
			case "pppoe":
2991
			case "pptp":
2992
			case "l2tp":
2993
			case "ppp";
2994
				$ints[$ifdescr] = $ifdescr;
2995
			break;
2996
			default:
2997
				if (!empty($ifname['gateway']))
2998
					$ints[$ifdescr] = $ifdescr;
2999
			break;
3000
		}
3001
	}
3002
	return $ints;
3003
}
3004

    
3005
/* return true if interface has a gateway */
3006
function interface_has_gateway($friendly) {
3007
	global $config;
3008

    
3009
	if (!empty($config['interfaces'][$friendly])) {
3010
		$ifname =& $config['interfaces'][$friendly];
3011
		switch ($ifname['ipaddr']) {
3012
			case "dhcp":
3013
			case "carpdev-dhcp":
3014
			case "pppoe":
3015
			case "pptp":
3016
			case "l2tp":
3017
			case "ppp";
3018
				return true;
3019
			break;
3020
			default:
3021
				if (!empty($ifname['gateway']))
3022
					return true;
3023
			break;
3024
		}
3025
	}
3026

    
3027
	return false;
3028
}
3029

    
3030
/****f* interfaces/is_altq_capable
3031
 * NAME
3032
 *   is_altq_capable - Test if interface is capable of using ALTQ
3033
 * INPUTS
3034
 *   $int            - string containing interface name
3035
 * RESULT
3036
 *   boolean         - true or false
3037
 ******/
3038

    
3039
function is_altq_capable($int) {
3040
        /* Per:
3041
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3042
         * Only the following drivers have ALTQ support
3043
         */
3044
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3045
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3046
			"hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe",
3047
			"npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk",
3048
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3049
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", "ppp");
3050

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

    
3053
        if (in_array($int_family[0], $capable))
3054
                return true;
3055
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
3056
		return true;
3057
        else
3058
                return false;
3059
}
3060

    
3061
/****f* interfaces/is_interface_wireless
3062
 * NAME
3063
 *   is_interface_wireless - Returns if an interface is wireless
3064
 * RESULT
3065
 *   $tmp       - Returns if an interface is wireless
3066
 ******/
3067
function is_interface_wireless($interface) {
3068
        global $config, $g;
3069

    
3070
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3071
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3072
                if (preg_match($g['wireless_regex'], $interface)) {
3073
                        $config['interfaces'][$friendly]['wireless'] = array();
3074
                        return true;
3075
                }
3076
                unset($config['interfaces'][$friendly]['wireless']);
3077
                return false;
3078
        } else
3079
                return true;
3080
}
3081

    
3082
function get_wireless_modes($interface) {
3083
	/* return wireless modes and channels */
3084
	$wireless_modes = array();
3085

    
3086
	$wlif = interface_translate_type_to_real($interface);
3087

    
3088
	if(is_interface_wireless($wlif)) {
3089
		$cloned_interface = get_real_interface($interface);
3090
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3091
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3092
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3093

    
3094
		$interface_channels = "";
3095
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3096
		$interface_channel_count = count($interface_channels);
3097

    
3098
		$c = 0;
3099
		while ($c < $interface_channel_count)
3100
		{
3101
			$channel_line = explode(",", $interface_channels["$c"]);
3102
			$wireless_mode = trim($channel_line[0]);
3103
			$wireless_channel = trim($channel_line[1]);
3104
			if(trim($wireless_mode) != "") {
3105
				/* if we only have 11g also set 11b channels */
3106
				if($wireless_mode == "11g") {
3107
					if(!isset($wireless_modes["11b"]))
3108
						$wireless_modes["11b"] = array();
3109
				} else if($wireless_mode == "11g ht") {
3110
					if(!isset($wireless_modes["11b"]))
3111
						$wireless_modes["11b"] = array();
3112
					if(!isset($wireless_modes["11g"]))
3113
						$wireless_modes["11g"] = array();
3114
					$wireless_mode = "11ng";
3115
				} else if($wireless_mode == "11a ht") {
3116
					if(!isset($wireless_modes["11a"]))
3117
						$wireless_modes["11a"] = array();
3118
					$wireless_mode = "11na";
3119
				}
3120
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3121
			}
3122
			$c++;
3123
		}
3124
	}
3125
	return($wireless_modes);
3126
}
3127

    
3128
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3129
function get_wireless_channel_info($interface) {
3130
	$wireless_channels = array();
3131

    
3132
	$wlif = interface_translate_type_to_real($interface);
3133

    
3134
	if(is_interface_wireless($wlif)) {
3135
		$cloned_interface = get_real_interface($interface);
3136
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3137
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3138
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3139

    
3140
		$interface_channels = "";
3141
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3142

    
3143
		foreach ($interface_channels as $channel_line) {
3144
			$channel_line = explode(",", $channel_line);
3145
			if(!isset($wireless_channels[$channel_line[0]]))
3146
				$wireless_channels[$channel_line[0]] = $channel_line;
3147
		}
3148
	}
3149
	return($wireless_channels);
3150
}
3151

    
3152
/****f* interfaces/get_interface_mtu
3153
 * NAME
3154
 *   get_interface_mtu - Return the mtu of an interface
3155
 * RESULT
3156
 *   $tmp       - Returns the mtu of an interface
3157
 ******/
3158
function get_interface_mtu($interface) {
3159
        $mtu = pfSense_get_interface_addresses($interface);
3160
        return $mtu['mtu'];
3161
}
3162

    
3163
function get_interface_mac($interface) {
3164

    
3165
	$macinfo = pfSense_get_interface_addresses($interface);
3166
	return $macinfo["macaddr"];
3167
}
3168

    
3169
/****f* pfsense-utils/generate_random_mac_address
3170
 * NAME
3171
 *   generate_random_mac - generates a random mac address
3172
 * INPUTS
3173
 *   none
3174
 * RESULT
3175
 *   $mac - a random mac address
3176
 ******/
3177
function generate_random_mac_address() {
3178
        $mac = "02";
3179
        for($x=0; $x<5; $x++)
3180
                $mac .= ":" . dechex(rand(16, 255));
3181
        return $mac;
3182
}
3183

    
3184
/****f* interfaces/is_jumbo_capable
3185
 * NAME
3186
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3187
 * INPUTS
3188
 *   $int             - string containing interface name
3189
 * RESULT
3190
 *   boolean          - true or false
3191
 ******/
3192
function is_jumbo_capable($int) {
3193
        global $g;
3194

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

    
3197
        if (in_array($int_family[0], $g['vlan_long_frame']))
3198
                return true;
3199
        else
3200
                return false;
3201
}
3202

    
3203
function setup_pppoe_reset_file($pppif, $iface="") {
3204
	global $g;
3205
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3206

    
3207
	if(!empty($iface) && !empty($pppif)){
3208
		$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";
3209
		file_put_contents($cron_file, $cron_cmd);
3210
		chmod($cron_file, 0700);
3211
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3212
	} else
3213
		unlink_if_exists($cron_file);
3214
}
3215

    
3216
?>
(21-21/50)