Project

General

Profile

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

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

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

    
876
	return;
877
}
878

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

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

    
887
	return false;
888
}
889

    
890
function interfaces_ptpid_next() {
891

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

    
896
	return $ptpid;
897
}
898

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1195
EOD;
1196

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

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

    
1210
EOD;
1211

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

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

    
1222
EOD;
1223

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

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

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

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

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

    
1250
EOD;
1251

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

    
1256
EOD;
1257

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

    
1262
EOD;
1263

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

    
1269
EOD;
1270

    
1271

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

    
1276
EOD;
1277

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

    
1283
EOD;
1284

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

    
1289
EOD;
1290

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

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

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

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

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

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

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

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

    
1344
EOD;
1345

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

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

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

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

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

    
1388
	return 1;
1389
}
1390

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1584
function interface_ipalias_configure(&$vip) {
1585

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1739
EOD;
1740

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

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

    
1751
	return $vipif;
1752
}
1753

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

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

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

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

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

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

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

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

    
1845
	// Read or write settings at shared area
1846
	if (isset($config['wireless']['interfaces'][$baseif])) {
1847
		foreach ($shared_settings as $setting) {
1848
			if ($sync_changes) {
1849
				$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
1850
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
1851
				$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
1852
			}
1853
		}
1854
	}
1855

    
1856
	// Sync the mode on the clone creation page with the configured mode on the interface
1857
	if (interface_is_wireless_clone($ifcfg['if'])) {
1858
		foreach ($config['wireless']['clone'] as &$clone) {
1859
			if ($clone['cloneif'] == $ifcfg['if']) {
1860
				if ($sync_changes) {
1861
					$clone['mode'] = $ifcfg['wireless']['mode'];
1862
				} else {
1863
					$ifcfg['wireless']['mode'] = $clone['mode'];
1864
				}
1865
				break;
1866
			}
1867
		}
1868
		unset($clone);
1869
	}
1870
}
1871

    
1872
function interface_wireless_configure($if, &$wl, &$wlcfg) {
1873
	global $config, $g;
1874

    
1875
	/*    open up a shell script that will be used to output the commands.
1876
	 *    since wireless is changing a lot, these series of commands are fragile
1877
     *    and will sometimes need to be verified by a operator by executing the command
1878
     *    and returning the output of the command to the developers for inspection.  please
1879
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1880
	 */
1881

    
1882
	// Remove script file
1883
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1884

    
1885
	// Clone wireless nic if needed.
1886
	interface_wireless_clone($if, $wl);
1887

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

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

    
1895
	/* set values for /path/program */
1896
	$hostapd = "/usr/sbin/hostapd";
1897
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1898
	$ifconfig = "/sbin/ifconfig";
1899
	$killall = "/usr/bin/killall";
1900

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

    
1903
	$wlcmd = array();
1904
	/* Make sure it's up */
1905
	$wlcmd[] = "up";
1906
	/* Set a/b/g standard */
1907
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
1908
	$wlcmd[] = "mode " . escapeshellarg($standard);
1909

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

    
1915
	/* Set ssid */
1916
	if($wlcfg['ssid'])
1917
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
1918

    
1919
	/* Set 802.11g protection mode */
1920
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
1921

    
1922
	/* set wireless channel value */
1923
	if(isset($wlcfg['channel'])) {
1924
		if($wlcfg['channel'] == "0") {
1925
			$wlcmd[] = "channel any";
1926
		} else {
1927
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
1928
		}
1929
	}
1930

    
1931
	/* set Distance value */
1932
	if($wlcfg['distance'])
1933
		$distance = escapeshellarg($wlcfg['distance']);
1934

    
1935
	/* Set wireless hostap mode */
1936
	if ($wlcfg['mode'] == "hostap") {
1937
		$wlcmd[] = "mediaopt hostap";
1938
	} else {
1939
		$wlcmd[] = "-mediaopt hostap";
1940
	}
1941

    
1942
	/* Set wireless adhoc mode */
1943
	if ($wlcfg['mode'] == "adhoc") {
1944
		$wlcmd[] = "mediaopt adhoc";
1945
	} else {
1946
		$wlcmd[] = "-mediaopt adhoc";
1947
	}
1948

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

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

    
1958
	/* handle pureg (802.11g) only option */
1959
	if(isset($wlcfg['pureg']['enable'])) {
1960
		$wlcmd[] = "mode 11g pureg";
1961
	} else {
1962
		$wlcmd[] = "-pureg";
1963
	}
1964

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

    
1972
	/* enable apbridge option */
1973
	if(isset($wlcfg['apbridge']['enable'])) {
1974
		$wlcmd[] = "apbridge";
1975
	} else {
1976
		$wlcmd[] = "-apbridge";
1977
	}
1978

    
1979
	/* handle turbo option */
1980
	if(isset($wlcfg['turbo']['enable'])) {
1981
		$wlcmd[] = "mediaopt turbo";
1982
	} else {
1983
		$wlcmd[] = "-mediaopt turbo";
1984
	}
1985

    
1986
	/* handle txpower setting */
1987
	/* if($wlcfg['txpower'] <> "")
1988
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
1989
	*/
1990
	/* handle wme option */
1991
	if(isset($wlcfg['wme']['enable'])) {
1992
		$wlcmd[] = "wme";
1993
	} else {
1994
		$wlcmd[] = "-wme";
1995
	}
1996

    
1997
	/* set up wep if enabled */
1998
	$wepset = "";
1999
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2000
		switch($wlcfg['wpa']['auth_algs']) {
2001
			case "1":
2002
				$wepset .= "authmode open wepmode on ";
2003
				break;
2004
			case "2":
2005
				$wepset .= "authmode shared wepmode on ";
2006
				break;
2007
			case "3":
2008
				$wepset .= "authmode mixed wepmode on ";
2009
		}
2010
		$i = 1;
2011
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2012
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2013
			if (isset($wepkey['txkey'])) {
2014
				$wlcmd[] = "weptxkey {$i} ";
2015
			}
2016
			$i++;
2017
		}
2018
		$wlcmd[] = $wepset;
2019
	} else {
2020
		$wlcmd[] = "authmode open wepmode off ";
2021
	}
2022

    
2023
	mwexec(kill_hostapd("{$if}"));
2024
	mwexec(kill_wpasupplicant("{$if}"));
2025

    
2026
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2027
	conf_mount_rw();
2028

    
2029
	switch ($wlcfg['mode']) {
2030
		case 'bss':
2031
			if (isset($wlcfg['wpa']['enable'])) {
2032
				$wpa .= <<<EOD
2033
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2034
ctrl_interface_group=0
2035
ap_scan=1
2036
#fast_reauth=1
2037
network={
2038
ssid="{$wlcfg['ssid']}"
2039
scan_ssid=1
2040
priority=5
2041
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2042
psk="{$wlcfg['wpa']['passphrase']}"
2043
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2044
group={$wlcfg['wpa']['wpa_pairwise']}
2045
}
2046
EOD;
2047

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

    
2086
EOD;
2087

    
2088
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2089
					$auth_server_port = "1812";
2090
					if($wlcfg['auth_server_port']) 
2091
						$auth_server_port = $wlcfg['auth_server_port'];
2092
					$wpa .= <<<EOD
2093

    
2094
ieee8021x=1
2095
auth_server_addr={$wlcfg['auth_server_addr']}
2096
auth_server_port={$auth_server_port}
2097
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2098

    
2099
EOD;
2100
				} else {
2101
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2102
				}
2103

    
2104
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2105
				fwrite($fd, "{$wpa}");
2106
				fclose($fd);
2107

    
2108
			}
2109
			break;
2110
	}
2111

    
2112
	/*
2113
	 *    all variables are set, lets start up everything
2114
	 */
2115

    
2116
	$baseif = interface_get_wireless_base($if);
2117

    
2118
	/* set ack timers according to users preference (if he/she has any) */
2119
	if($distance) {
2120
		fwrite($fd_set, "# Enable ATH distance settings\n");
2121
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2122
	}
2123

    
2124
	if (isset($wlcfg['wpa']['enable'])) {
2125
		if ($wlcfg['mode'] == "bss") {
2126
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2127
		}
2128
		if ($wlcfg['mode'] == "hostap") {
2129
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
2130
		}
2131
	}
2132

    
2133
	fclose($fd_set);
2134
	conf_mount_ro();
2135

    
2136
	/* Making sure regulatory settings have actually changed
2137
	 * before applying, because changing them requires bringing
2138
	 * down all wireless networks on the interface. */
2139
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2140
	$ifconfig_str = implode($output);
2141
	unset($output);
2142
	$reg_changing = false;
2143

    
2144
	/* special case for the debug country code */
2145
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2146
		$reg_changing = true;
2147
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2148
		$reg_changing = true;
2149
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2150
		$reg_changing = true;
2151
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2152
		$reg_changing = true;
2153
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2154
		$reg_changing = true;
2155

    
2156
	if ($reg_changing) {
2157
		/* set regulatory domain */
2158
		if($wlcfg['regdomain'])
2159
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2160

    
2161
		/* set country */
2162
		if($wlcfg['regcountry'])
2163
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2164

    
2165
		/* set location */
2166
		if($wlcfg['reglocation'])
2167
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2168

    
2169
		$wlregcmd_args = implode(" ", $wlregcmd);
2170

    
2171
		/* build a complete list of the wireless clones for this interface */
2172
		$clone_list = array();
2173
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2174
			$clone_list[] = interface_get_wireless_clone($baseif);
2175
		if (is_array($config['wireless']['clone'])) {
2176
			foreach ($config['wireless']['clone'] as $clone) {
2177
				if ($clone['if'] == $baseif)
2178
					$clone_list[] = $clone['cloneif'];
2179
			}
2180
		}
2181

    
2182
		/* find which clones are up and bring them down */
2183
		$clones_up = array();
2184
		foreach ($clone_list as $clone_if) {
2185
			$clone_status = pfSense_get_interface_addresses($clone_if);
2186
			if ($clone_status['status'] == 'up') {
2187
				$clones_up[] = $clone_if;
2188
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2189
			}
2190
		}
2191

    
2192
		/* apply the regulatory settings */
2193
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2194

    
2195
		/* bring the clones back up that were previously up */
2196
		foreach ($clones_up as $clone_if) {
2197
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2198
		}
2199
	}
2200

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

    
2205
	/* configure wireless */
2206
	$wlcmd_args = implode(" ", $wlcmd);
2207
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2208

    
2209
	
2210
	sleep(1);
2211
	/* execute hostapd and wpa_supplicant if required in shell */
2212
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2213

    
2214
	return 0;
2215

    
2216
}
2217

    
2218
function kill_hostapd($interface) {
2219
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2220
}
2221

    
2222
function kill_wpasupplicant($interface) {
2223
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2224
}
2225

    
2226
function find_dhclient_process($interface) {
2227
	if($interface) {
2228
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
2229
	}
2230
	return $pid;
2231
}
2232

    
2233
function interface_configure($interface = "wan", $reloadall = false) {
2234
	global $config, $g;
2235
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2236

    
2237
	$wancfg = $config['interfaces'][$interface];
2238

    
2239
	$realif = get_real_interface($interface);
2240

    
2241
	if (!$g['booting']) {
2242
		/* remove all IPv4 addresses */
2243
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2244
			interface_bring_down($interface, true);
2245
	}
2246

    
2247
	/* wireless configuration? */
2248
	if (is_array($wancfg['wireless']))
2249
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2250

    
2251
	if ($wancfg['spoofmac']) {
2252
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
2253
			" link " . escapeshellarg($wancfg['spoofmac']));
2254

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

    
2282
	/* media */
2283
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2284
		$cmd = "/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if']));
2285
		if ($wancfg['media'])
2286
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2287
		if ($wancfg['mediaopt'])
2288
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2289
		mwexec($cmd);
2290
	}
2291
	if (!empty($wancfg['mtu']))
2292
		pfSense_interface_mtu($realif, $wancfg['mtu']);
2293

    
2294
	/* invalidate interface/ip/sn cache */
2295
	get_interface_arr(true);
2296
	unset($interface_ip_arr_cache[$realif]);
2297
	unset($interface_sn_arr_cache[$realif]);
2298

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

    
2331
			if (is_ipaddr($wancfg['gateway']))
2332
				file_put_contents("{$g['tmp_path']}/{$realif}_router", $wancfg['gateway']);
2333
			break;
2334
	}
2335

    
2336
	if(does_interface_exist($wancfg['if']))
2337
		interfaces_bring_up($wancfg['if']);
2338
 	
2339
	if (!$g['booting'])
2340
		interface_reload_carps($realif);
2341
	
2342
	if (!$g['booting']) {
2343
		unset($gre);
2344
		$gre = link_interface_to_gre($interface);
2345
		if (!empty($gre))
2346
			interface_gre_configure($gre);
2347

    
2348
		unset($gif);
2349
		$gif = link_interface_to_gif($interface);
2350
		if (!empty($gif))
2351
                       	interface_gif_configure($gif);
2352

    
2353
		unset($bridgetmp);
2354
		$bridgetmp = link_interface_to_bridge($interface);
2355
		if (!empty($bridgetmp))
2356
			interface_bridge_add_member($bridgetmp, $realif);
2357

    
2358
		link_interface_to_vips($interface, "update");
2359

    
2360
		if ($interface == "lan")
2361
			/* make new hosts file */
2362
			system_hosts_generate();
2363

    
2364
		if ($reloadall == true) {
2365

    
2366
			/* reconfigure static routes (kernel may have deleted them) */
2367
			system_routing_configure($interface);
2368

    
2369
			/* reload ipsec tunnels */
2370
			vpn_ipsec_configure();
2371

    
2372
			/* update dyndns */
2373
			services_dyndns_configure($interface);
2374

    
2375
			/* force DNS update */
2376
			services_dnsupdate_process($interface);
2377

    
2378
			/* restart dnsmasq */
2379
			services_dnsmasq_configure();
2380

    
2381
			/* reload captive portal */
2382
			captiveportal_init_rules();
2383

    
2384
			/* set the reload filter dity flag */
2385
			filter_configure();
2386
		}
2387
	}
2388

    
2389
	return 0;
2390
}
2391

    
2392
function interface_carpdev_dhcp_configure($interface = "wan") {
2393
	global $config, $g;
2394

    
2395
	$wancfg = $config['interfaces'][$interface];
2396
	$wanif = $wancfg['if'];
2397
	/* bring wan interface up before starting dhclient */
2398
	if($wanif)
2399
		interfaces_bring_up($wanif);
2400
	else 
2401
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2402

    
2403
	return 0;
2404
}
2405

    
2406
function interface_dhcp_configure($interface = "wan") {
2407
	global $config, $g;
2408

    
2409
	$wancfg = $config['interfaces'][$interface];
2410
	if (empty($wancfg))
2411
		$wancfg = array();
2412

    
2413
	/* generate dhclient_wan.conf */
2414
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2415
	if (!$fd) {
2416
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2417
		return 1;
2418
	}
2419

    
2420
	if ($wancfg['dhcphostname']) {
2421
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2422
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2423
	} else {
2424
		$dhclientconf_hostname = "";
2425
	}
2426

    
2427
	$wanif = get_real_interface($interface);
2428
	if (empty($wanif)) {
2429
		log_error("Invalid interface \"{$interface}\" in interface_dhcp_configure()");
2430
		return 0;
2431
	}
2432
 	$dhclientconf = "";
2433
	
2434
	$dhclientconf .= <<<EOD
2435
interface "{$wanif}" {
2436
timeout 60;
2437
retry 1;
2438
select-timeout 0;
2439
initial-interval 1;
2440
	{$dhclientconf_hostname}
2441
	script "/sbin/dhclient-script";
2442
}
2443

    
2444
EOD;
2445

    
2446
if(is_ipaddr($wancfg['alias-address'])) {
2447
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2448
	$dhclientconf .= <<<EOD
2449
alias {
2450
	interface  "{$wanif}";
2451
	fixed-address {$wancfg['alias-address']};
2452
	option subnet-mask {$subnetmask};
2453
}
2454

    
2455
EOD;
2456
}
2457
	fwrite($fd, $dhclientconf);
2458
	fclose($fd);
2459

    
2460
	/* bring wan interface up before starting dhclient */
2461
	if($wanif)
2462
		interfaces_bring_up($wanif);
2463
	else 
2464
		log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
2465

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

    
2469
	return 0;
2470
}
2471

    
2472
function interfaces_group_setup() {
2473
	global $config;
2474

    
2475
	if (!is_array($config['ifgroups']['ifgroupentry']))
2476
		return;
2477

    
2478
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2479
		interface_group_setup($groupar);
2480

    
2481
	return;
2482
}
2483

    
2484
function interface_group_setup(&$groupname /* The parameter is an array */) {
2485
	global $config;
2486

    
2487
	if (!is_array($groupname))
2488
		return;
2489
	$members = explode(" ", $groupname['members']);
2490
	foreach($members as $ifs) {
2491
		$realif = get_real_interface($ifs);
2492
		if ($realif)
2493
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2494
	}
2495

    
2496
	return;
2497
}
2498
 
2499
/* COMPAT Function */
2500
function convert_friendly_interface_to_real_interface_name($interface) {
2501
	return get_real_interface($interface);
2502
}
2503

    
2504
/* COMPAT Function */
2505
function get_real_wan_interface($interface = "wan") {
2506
	return get_real_interface($interface);
2507
}
2508

    
2509
/* COMPAT Function */
2510
function get_current_wan_address($interface = "wan") {
2511
	return get_interface_ip($interface);
2512
}
2513

    
2514
/*
2515
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2516
 */
2517
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2518
        global $config;
2519

    
2520
	if (stristr($interface, "vip")) {
2521
                $index = intval(substr($interface, 3));
2522
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2523
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2524
                                if ($index == $counter)
2525
                                        return $vip['interface'];
2526
                        }
2527
                }
2528
        } else if (stristr($interface, "carp")) {
2529
                $index = intval(substr($interface, 4));
2530
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2531
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2532
                                if ($index == $counter)
2533
                                        return $vip['interface'];
2534
                        }
2535
                }
2536
        }
2537

    
2538
        /* XXX: For speed reasons reference directly the interface array */
2539
	$ifdescrs = $config['interfaces'];
2540
        //$ifdescrs = get_configured_interface_list(false, true);
2541

    
2542
        foreach ($ifdescrs as $if => $ifname) {
2543
                if ($config['interfaces'][$if]['if'] == $interface)
2544
                        return $if;
2545

    
2546
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2547
                $int = interface_translate_type_to_real($if);
2548
                if ($int == $interface)
2549
                        return $ifname;
2550
        }
2551
        return NULL;
2552
}
2553

    
2554
/* attempt to resolve interface to friendly descr */
2555
function convert_friendly_interface_to_friendly_descr($interface) {
2556
        global $config;
2557

    
2558
        switch ($interface) {
2559
                case "l2tp":
2560
                                $ifdesc = "L2TP";
2561
                                break;
2562
                case "pptp":
2563
                                $ifdesc = "pptp";
2564
                                break;
2565
                case "pppoe":
2566
                                $ifdesc = "pppoe";
2567
                                break;
2568
                case "openvpn":
2569
                                $ifdesc = "OpenVPN";
2570
                                break;
2571
                case "enc0":
2572
                        case "ipsec":
2573
                                $ifdesc = "IPsec";
2574
                                break;
2575
        default:
2576
                /* if list */
2577
                $ifdescrs = get_configured_interface_with_descr(false, true);
2578
                foreach ($ifdescrs as $if => $ifname) {
2579
                                if ($if == $interface || $ifname == $interface)
2580
                                        return $ifname;
2581
                }
2582
                break;
2583
        }
2584

    
2585
        return $ifdesc;
2586
}
2587

    
2588
function convert_real_interface_to_friendly_descr($interface) {
2589
        global $config;
2590

    
2591
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2592

    
2593
        if ($ifdesc) {
2594
                $iflist = get_configured_interface_with_descr(false, true);
2595
                return $iflist[$ifdesc];
2596
        }
2597

    
2598
        return $interface;
2599
}
2600

    
2601
/*
2602
 *  interface_translate_type_to_real($interface):
2603
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2604
 */
2605
function interface_translate_type_to_real($interface) {
2606
        global $config;
2607

    
2608
        if ($config['interfaces'][$interface]['if'] <> "")
2609
                return $config['interfaces'][$interface]['if'];
2610
        else
2611
		return $interface;
2612
}
2613

    
2614
function interface_is_wireless_clone($wlif) {
2615
	if(!stristr($wlif, "_wlan")) {
2616
		return false;
2617
	} else {
2618
		return true;
2619
	}
2620
}
2621

    
2622
function interface_get_wireless_base($wlif) {
2623
	if(!stristr($wlif, "_wlan")) {
2624
		return $wlif;
2625
	} else {
2626
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2627
	}
2628
}
2629

    
2630
function interface_get_wireless_clone($wlif) {
2631
	if(!stristr($wlif, "_wlan")) {
2632
		return $wlif . "_wlan0";
2633
	} else {
2634
		return $wlif;
2635
	}
2636
}
2637

    
2638
function get_real_interface($interface = "wan") {
2639
    global $config;
2640

    
2641
	$wanif = NULL;
2642

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

    
2675
		$cfg =& $config['interfaces'][$interface];
2676

    
2677
		// Wireless cloned NIC support (FreeBSD 8+)
2678
		// interface name format: $parentnic_wlanparentnic#
2679
		// example: ath0_wlan0
2680
		if (is_interface_wireless($cfg['if'])) {
2681
			$wanif = interface_get_wireless_clone($cfg['if']);
2682
			break;
2683
		}
2684
		/*
2685
		if (empty($cfg['if'])) {
2686
			$wancfg = $cfg['if'];
2687
			break;
2688
		}
2689
		*/
2690

    
2691
		switch ($cfg['ipaddr']) {
2692
			case "carpdev-dhcp":
2693
				$viparr = &$config['virtualip']['vip'];
2694
				if(is_array($viparr))
2695
				foreach ($viparr as $counter => $vip) {
2696
					if ($vip['mode'] == "carpdev-dhcp") {
2697
						if($vip['interface'] == $interface) {
2698
							$wanif = "carp{$counter}";
2699
							break;
2700
						}
2701
					}
2702
				}
2703
				break;
2704
			case "pppoe": 
2705
			case "pptp": 
2706
			case "l2tp": 
2707
			case "ppp":
2708
				$wanif = $cfg['if'];
2709
				break;
2710
			default:
2711
				$wanif = $cfg['if'];
2712
				break;
2713
		}
2714
		break;
2715
	}
2716

    
2717
    return $wanif;
2718
}
2719

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

    
2742
/*
2743
 * find_ip_interface($ip): return the interface where an ip is defined
2744
 */
2745
function find_ip_interface($ip)
2746
{
2747
        /* if list */
2748
        $ifdescrs = get_configured_interface_list();
2749

    
2750
        foreach ($ifdescrs as $ifdescr => $ifname) {
2751
		if ($ip == get_interface_ip($ifname)) {
2752
                	$int = get_real_interface($ifname);
2753
			return $int;
2754
		}
2755
        }
2756
        return false;
2757
}
2758

    
2759
/*
2760
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
2761
 */
2762
function find_number_of_created_carp_interfaces() {
2763
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
2764
}
2765

    
2766
function get_all_carp_interfaces() {
2767
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
2768
	$ints = explode(" ", $ints);
2769
	return $ints;
2770
}
2771

    
2772
/*
2773
 * find_carp_interface($ip): return the carp interface where an ip is defined
2774
 */
2775
function find_carp_interface($ip) {
2776
	global $config;
2777
	if (is_array($config['virtualip']['vip'])) {
2778
		foreach ($config['virtualip']['vip'] as $vip) {
2779
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2780
				$carp_ip = get_interface_ip($vip['interface']);
2781
				$if = `ifconfig | grep '$ip ' -B1 | head -n1 | cut -d: -f1`;
2782
				if ($if)
2783
					return $if;
2784
			}
2785
		}
2786
	}
2787
}
2788

    
2789
function link_carp_interface_to_parent($interface) {
2790
        global $config;
2791

    
2792
        if ($interface == "")
2793
                return;
2794

    
2795
        $carp_ip = get_interface_ip($interface);
2796
        if (!is_ipaddr($carp_ip))
2797
                return;
2798

    
2799
        /* if list */
2800
        $ifdescrs = get_configured_interface_list();
2801
        foreach ($ifdescrs as $ifdescr => $ifname) {
2802
                $interfaceip = get_interface_ip($ifname);
2803
                $subnet_bits = get_interface_subnet($ifname);
2804
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
2805
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
2806
                        return $ifname;
2807
        }
2808

    
2809
        return "";
2810
}
2811

    
2812
/****f* interfaces/link_ip_to_carp_interface
2813
 * NAME
2814
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
2815
 * INPUTS
2816
 *   $ip
2817
 * RESULT
2818
 *   $carp_ints
2819
 ******/
2820
function link_ip_to_carp_interface($ip) {
2821
        global $config;
2822

    
2823
        if (!is_ipaddr($ip))
2824
                return;
2825

    
2826
        $carp_ints = "";
2827
        if (is_array($config['virtualip']['vip'])) {
2828
		$first = 0;
2829
		$carp_int = array();
2830
                foreach ($config['virtualip']['vip'] as $vip) {
2831
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2832
                                $carp_ip = $vip['subnet'];
2833
                                $carp_sn = $vip['subnet_bits'];
2834
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
2835
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
2836
					$carp_int[] = "vip{$vip['vhid']}";
2837
                        }
2838
                }
2839
		if (!empty($carp_int))
2840
			$carp_ints = implode(" ", array_unique($carp_int));
2841
        }
2842

    
2843
        return $carp_ints;
2844
}
2845

    
2846
function link_interface_to_vlans($int, $action = "") {
2847
	global $config;
2848

    
2849
	if (empty($int))
2850
		return;
2851

    
2852
	if (is_array($config['vlans']['vlan'])) {
2853
                foreach ($config['vlans']['vlan'] as $vlan) {
2854
			if ($int == $vlan['if']) {
2855
				if ($action == "update") {
2856
					interfaces_bring_up($int);
2857
				} else if ($action == "")
2858
					return $vlan;
2859
			}
2860
		}
2861
	}
2862
}
2863

    
2864
function link_interface_to_vips($int, $action = "") {
2865
        global $config;
2866

    
2867
        if (is_array($config['virtualip']['vip']))
2868
                foreach ($config['virtualip']['vip'] as $vip)
2869
                        if ($int == $vip['interface']) {
2870
				if ($action == "update")
2871
					interfaces_vips_configure($int);
2872
				else
2873
                                	return $vip;
2874
			}
2875
}
2876

    
2877
/****f* interfaces/link_interface_to_bridge
2878
 * NAME
2879
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2880
 * INPUTS
2881
 *   $ip
2882
 * RESULT
2883
 *   bridge[0-99]
2884
 ******/
2885
function link_interface_to_bridge($int) {
2886
        global $config;
2887

    
2888
        if (is_array($config['bridges']['bridged'])) {
2889
                foreach ($config['bridges']['bridged'] as $bridge) {
2890
			if (in_array($int, explode(',', $bridge['members'])))
2891
                                return "{$bridge['bridgeif']}";
2892
		}
2893
	}
2894
}
2895

    
2896
function link_interface_to_gre($interface) {
2897
        global $config;
2898

    
2899
        if (is_array($config['gres']['gre']))
2900
                foreach ($config['gres']['gre'] as $gre)
2901
                        if($gre['if'] == $interface)
2902
                                return $gre;
2903
}
2904

    
2905
function link_interface_to_gif($interface) {
2906
        global $config;
2907

    
2908
        if (is_array($config['gifs']['gif']))
2909
                foreach ($config['gifs']['gif'] as $gif)
2910
                        if($gif['if'] == $interface)
2911
                                return $gif;
2912
}
2913

    
2914
/*
2915
 * find_interface_ip($interface): return the interface ip (first found)
2916
 */
2917
function find_interface_ip($interface, $flush = false)
2918
{
2919
	global $interface_ip_arr_cache;
2920

    
2921
	$interface = str_replace("\n", "", $interface);
2922
	
2923
	if (!does_interface_exist($interface))
2924
		return;
2925

    
2926
	/* Setup IP cache */
2927
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2928
		$ifinfo = pfSense_get_interface_addresses($interface);
2929
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
2930
	}
2931

    
2932
	return $interface_ip_arr_cache[$interface];
2933
}
2934

    
2935
function find_interface_subnet($interface, $flush = false)
2936
{
2937
	global $interface_sn_arr_cache;
2938

    
2939
	$interface = str_replace("\n", "", $interface);
2940
	if (does_interface_exist($interface) == false)
2941
		return;
2942

    
2943
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2944
		$ifinfo = pfSense_get_interface_addresses($interface);
2945
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
2946
        }
2947

    
2948
	return $interface_sn_arr_cache[$interface];
2949
}
2950

    
2951
function get_interface_ip($interface = "wan")
2952
{
2953
	$realif = get_real_interface($interface);
2954
	if (!$realif) {
2955
		if (preg_match("/^carp/i", $interface))
2956
			$realif = $interface;
2957
		else if (preg_match("/^vip/i", $interface))
2958
			$realif = $interface;
2959
		else
2960
			return null;
2961
	}
2962

    
2963
	$curip = find_interface_ip($realif);
2964
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2965
		return $curip;
2966
	else
2967
		return null;
2968
}
2969

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

    
2982
	$cursn = find_interface_subnet($realif);
2983
	if (!empty($cursn))
2984
		return $cursn;
2985

    
2986
	return null;
2987
}
2988

    
2989
/* return outside interfaces with a gateway */
2990
function get_interfaces_with_gateway() {
2991
	global $config;
2992

    
2993
	$ints = array();
2994

    
2995
	/* loop interfaces, check config for outbound */
2996
	foreach($config['interfaces'] as $ifdescr => $ifname) {
2997
		if (substr($ifdescr, 0, 5) ==  "ovpnc")
2998
			return true;
2999

    
3000
		switch ($ifname['ipaddr']) {
3001
			case "dhcp":
3002
			case "carpdev-dhcp":
3003
			case "ppp";
3004
			case "pppoe":
3005
			case "pptp":
3006
			case "l2tp":
3007
			case "ppp";
3008
				$ints[$ifdescr] = $ifdescr;
3009
			break;
3010
			default:
3011
				if (!empty($ifname['gateway']))
3012
					$ints[$ifdescr] = $ifdescr;
3013
			break;
3014
		}
3015
	}
3016
	return $ints;
3017
}
3018

    
3019
/* return true if interface has a gateway */
3020
function interface_has_gateway($friendly) {
3021
	global $config;
3022

    
3023
	if (!empty($config['interfaces'][$friendly])) {
3024
		if (substr($friendly, 0, 5) ==  "ovpnc")
3025
			return true;
3026
		$ifname =& $config['interfaces'][$friendly];
3027
		switch ($ifname['ipaddr']) {
3028
			case "dhcp":
3029
			case "carpdev-dhcp":
3030
			case "pppoe":
3031
			case "pptp":
3032
			case "l2tp":
3033
			case "ppp";
3034
				return true;
3035
			break;
3036
			default:
3037
				if (!empty($ifname['gateway']))
3038
					return true;
3039
			break;
3040
		}
3041
	}
3042

    
3043
	return false;
3044
}
3045

    
3046
/****f* interfaces/is_altq_capable
3047
 * NAME
3048
 *   is_altq_capable - Test if interface is capable of using ALTQ
3049
 * INPUTS
3050
 *   $int            - string containing interface name
3051
 * RESULT
3052
 *   boolean         - true or false
3053
 ******/
3054

    
3055
function is_altq_capable($int) {
3056
        /* Per:
3057
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3058
         * Only the following drivers have ALTQ support
3059
         */
3060
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3061
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3062
			"hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe",
3063
			"npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk",
3064
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3065
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", "ppp");
3066

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

    
3069
        if (in_array($int_family[0], $capable))
3070
                return true;
3071
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
3072
		return true;
3073
        else
3074
                return false;
3075
}
3076

    
3077
/****f* interfaces/is_interface_wireless
3078
 * NAME
3079
 *   is_interface_wireless - Returns if an interface is wireless
3080
 * RESULT
3081
 *   $tmp       - Returns if an interface is wireless
3082
 ******/
3083
function is_interface_wireless($interface) {
3084
        global $config, $g;
3085

    
3086
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3087
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3088
                if (preg_match($g['wireless_regex'], $interface)) {
3089
                        $config['interfaces'][$friendly]['wireless'] = array();
3090
                        return true;
3091
                }
3092
                unset($config['interfaces'][$friendly]['wireless']);
3093
                return false;
3094
        } else
3095
                return true;
3096
}
3097

    
3098
function get_wireless_modes($interface) {
3099
	/* return wireless modes and channels */
3100
	$wireless_modes = array();
3101

    
3102
	$wlif = interface_translate_type_to_real($interface);
3103

    
3104
	if(is_interface_wireless($wlif)) {
3105
		$cloned_interface = get_real_interface($interface);
3106
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3107
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3108
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3109

    
3110
		$interface_channels = "";
3111
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3112
		$interface_channel_count = count($interface_channels);
3113

    
3114
		$c = 0;
3115
		while ($c < $interface_channel_count)
3116
		{
3117
			$channel_line = explode(",", $interface_channels["$c"]);
3118
			$wireless_mode = trim($channel_line[0]);
3119
			$wireless_channel = trim($channel_line[1]);
3120
			if(trim($wireless_mode) != "") {
3121
				/* if we only have 11g also set 11b channels */
3122
				if($wireless_mode == "11g") {
3123
					if(!isset($wireless_modes["11b"]))
3124
						$wireless_modes["11b"] = array();
3125
				} else if($wireless_mode == "11g ht") {
3126
					if(!isset($wireless_modes["11b"]))
3127
						$wireless_modes["11b"] = array();
3128
					if(!isset($wireless_modes["11g"]))
3129
						$wireless_modes["11g"] = array();
3130
					$wireless_mode = "11ng";
3131
				} else if($wireless_mode == "11a ht") {
3132
					if(!isset($wireless_modes["11a"]))
3133
						$wireless_modes["11a"] = array();
3134
					$wireless_mode = "11na";
3135
				}
3136
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3137
			}
3138
			$c++;
3139
		}
3140
	}
3141
	return($wireless_modes);
3142
}
3143

    
3144
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3145
function get_wireless_channel_info($interface) {
3146
	$wireless_channels = array();
3147

    
3148
	$wlif = interface_translate_type_to_real($interface);
3149

    
3150
	if(is_interface_wireless($wlif)) {
3151
		$cloned_interface = get_real_interface($interface);
3152
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3153
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3154
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3155

    
3156
		$interface_channels = "";
3157
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3158

    
3159
		foreach ($interface_channels as $channel_line) {
3160
			$channel_line = explode(",", $channel_line);
3161
			if(!isset($wireless_channels[$channel_line[0]]))
3162
				$wireless_channels[$channel_line[0]] = $channel_line;
3163
		}
3164
	}
3165
	return($wireless_channels);
3166
}
3167

    
3168
/****f* interfaces/get_interface_mtu
3169
 * NAME
3170
 *   get_interface_mtu - Return the mtu of an interface
3171
 * RESULT
3172
 *   $tmp       - Returns the mtu of an interface
3173
 ******/
3174
function get_interface_mtu($interface) {
3175
        $mtu = pfSense_get_interface_addresses($interface);
3176
        return $mtu['mtu'];
3177
}
3178

    
3179
function get_interface_mac($interface) {
3180

    
3181
	$macinfo = pfSense_get_interface_addresses($interface);
3182
	return $macinfo["macaddr"];
3183
}
3184

    
3185
/****f* pfsense-utils/generate_random_mac_address
3186
 * NAME
3187
 *   generate_random_mac - generates a random mac address
3188
 * INPUTS
3189
 *   none
3190
 * RESULT
3191
 *   $mac - a random mac address
3192
 ******/
3193
function generate_random_mac_address() {
3194
        $mac = "02";
3195
        for($x=0; $x<5; $x++)
3196
                $mac .= ":" . dechex(rand(16, 255));
3197
        return $mac;
3198
}
3199

    
3200
/****f* interfaces/is_jumbo_capable
3201
 * NAME
3202
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3203
 * INPUTS
3204
 *   $int             - string containing interface name
3205
 * RESULT
3206
 *   boolean          - true or false
3207
 ******/
3208
function is_jumbo_capable($int) {
3209
        global $g;
3210

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

    
3213
        if (in_array($int_family[0], $g['vlan_long_frame']))
3214
                return true;
3215
        else
3216
                return false;
3217
}
3218

    
3219
function setup_pppoe_reset_file($pppif, $iface="") {
3220
	global $g;
3221
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3222

    
3223
	if(!empty($iface) && !empty($pppif)){
3224
		$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";
3225
		file_put_contents($cron_file, $cron_cmd);
3226
		chmod($cron_file, 0700);
3227
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3228
	} else
3229
		unlink_if_exists($cron_file);
3230
}
3231

    
3232
?>
(21-21/51)