Project

General

Profile

Download (47.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services.inc
5
	part of the pfSense project (http://www.pfsense.com)
6

    
7
	originally part of m0n0wall (http://m0n0.ch/wall)
8
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
9
	Copyright (C) 2010	Ermal Lu?i
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

    
18
	2. Redistributions in binary form must reproduce the above copyright
19
	   notice, this list of conditions and the following disclaimer in the
20
	   documentation and/or other materials provided with the distribution.
21

    
22
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
	POSSIBILITY OF SUCH DAMAGE.
32
*/
33

    
34
/*
35
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/bin/pgrep	/bin/sh	/usr/local/sbin/dhcpd	/usr/local/sbin/igmpproxy
36
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/usr/sbin/arp	/sbin/ifconfig	/usr/local/sbin/dnsmasq
37
	pfSense_BUILDER_BINARIES:	/usr/sbin/bsnmpd	/sbin/route	/usr/local/sbin/olsrd
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/miniupnpd	/usr/sbin/rtadvd
39
	pfSense_MODULE:	utils
40
*/
41

    
42
/* implement ipv6 route advertising deamon */
43
function services_rtadvd_configure() {
44
	global $config, $g;
45
	
46
	if(isset($config['system']['developerspew'])) {
47
		$mt = microtime();
48
		echo "services_rtadvd_configure() being called $mt\n";
49
	}
50

    
51
	if($g['services_dhcp_server_enable'] == false) 
52
		return;
53

    
54
	if(is_process_running("rtadvd")) {
55
		mwexec("killall -9 rtadvd", true);
56
	}
57

    
58
	/* DHCP enabled on any interfaces? */
59
	if (!is_dhcp_server_enabled())
60
		return 0;
61

    
62
	if (!is_array($config['dhcpdv6']))
63
		$config['dhcpdv6'] = array();
64

    
65
	$dhcpdv6cfg = $config['dhcpdv6'];
66
	$Iflist = get_configured_interface_list();
67

    
68
	/* write rtadvd.conf */
69
	$fd = fopen("{$g['varetc_path']}/rtadvd.conf", "w");
70
	if (!$fd) {
71
		printf("Error: cannot open rtadvd.conf in services_rtadvd_configure().\n");
72
		return 1;
73
	}
74

    
75
	/* raflags, managed=64, stateful=128, both=192 */
76

    
77
	$rtadvdconf = "# Automatically Generated, do not edit\n";
78
	$rtadvdconf = <<<EOD
79

    
80
#
81
# common definitions.
82
#
83
default:\
84
        :raflags#0:rltime#3600:\
85
        :pinfoflags#64:vltime#360000:pltime#360000:mtu#1500:
86
ether:\
87
        :mtu#1280:tc=default:
88

    
89
EOD;
90

    
91
	$rtadvdnum = 0;
92
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
93
		$rtadvdnum++;
94
		/* It appears we can not advertise the gateway IP (carp)
95
		 * 	rtadvd[44205]: <sock_open> IPV6_JOIN_GROUP(link) on vip1: Can't assign requested address
96
		if($dhcpv6ifconf['gateway'] <> "") {
97
			$dhcpv6if = find_carp_interface($dhcpv6ifconf['gateway']);
98
		}
99
		*/
100
		$realif = get_real_interface($dhcpv6if);
101

    
102
		$rtadvdifs[] = $realif;
103

    
104
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
105
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
106
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
107
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
108

    
109
		$rtadvdconf .= "{$realif}:\\\n";
110
		$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
111
		$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
112
		switch($dhcpv6ifconf['mode']) {
113
			case "managed":
114
				$rtadvdconf .= "\t:raflags#64:\\\n";
115
				break;
116
			case "assist":
117
				$rtadvdconf .= "\t:raflags#192:\\\n";
118
				break;
119
			default:
120
				$rtadvdconf .= "\t:raflags#0:\\\n";
121
				break;				
122

    
123
		}
124
		$rtadvdconf .= "\t\":tc=ether:\n";
125
		$rtadvdconf .= "\n\n";
126

    
127
	}
128

    
129
	fwrite($fd, $rtadvdconf);
130
	fclose($fd);
131

    
132
	if(count($rtadvdifs) > 0) {
133
		mwexec("/usr/sbin/rtadvd -c {$g['varetc_path']}/rtadvd.conf " . join(" ", $rtadvdifs));
134
	}
135
	return 0;
136
}
137

    
138
function services_dhcpd_configure() {
139
	global $config, $g;
140
	
141
	if($g['services_dhcp_server_enable'] == false) 
142
		return;
143

    
144
	if(isset($config['system']['developerspew'])) {
145
		$mt = microtime();
146
		echo "services_dhcpd_configure($if) being called $mt\n";
147
	}
148
	
149
	/* kill any running dhcpd */
150
	if(is_process_running("dhcpd")) {
151
		mwexec("killall dhcpd", true);
152
	}
153

    
154
	/* DHCP enabled on any interfaces? */
155
	if (!is_dhcp_server_enabled())
156
		return 0;
157

    
158
	/* if OLSRD is enabled, allow WAN to house DHCP. */
159
	if($config['installedpackages']['olsrd'])
160
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
161
				if($olsrd['enable'])
162
					$is_olsr_enabled = true;
163

    
164
	/* configure DHCPD chroot */
165
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
166
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
167
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
168
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
169
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
170
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
171
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
172
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
173
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
174
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
175
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
176
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
177
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
178
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
179
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
180
	if(!trim($status))
181
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
182
	fclose($fd);
183
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
184

    
185
	if ($g['booting']) {
186
		if ($g['platform'] != "pfSense") {
187
			/* restore the leases, if we have them */
188
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
189
				$dhcprestore = "";
190
				$dhcpreturn = "";
191
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
192
				$dhcprestore = implode(" ", $dhcprestore);
193
				if($dhcpreturn <> 0) {
194
					log_error("DHCP leases restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
195
				}
196
			}
197
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
198
				$dhcprestore = "";
199
				$dhcpreturn = "";
200
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
201
				$dhcprestore = implode(" ", $dhcprestore);
202
				if($dhcpreturn <> 0) {
203
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
204
				}
205
			}
206
		}
207
	}
208

    
209
	$syscfg = $config['system'];
210
	if (!is_array($config['dhcpd']))
211
		$config['dhcpd'] = array();
212
	if (!is_array($config['dhcpdv6']))
213
		$config['dhcpdv6'] = array();
214
	$dhcpdcfg = $config['dhcpd'];
215
	$dhcpdv6cfg = $config['dhcpdv6'];
216
	$Iflist = get_configured_interface_list();
217
		
218
	if ($g['booting'])
219
		echo "Starting DHCP service...";
220
	else
221
		sleep(1);
222

    
223
	/* write dhcpd.conf */
224
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
225
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
226
	if ((!$fd) || (! $fdv6)) {
227
		printf("Error: cannot open dhcpd.conf or dhcpdv6.conf in services_dhcpd_configure().\n");
228
		return 1;
229
	}
230

    
231
	$custoptions = "";
232
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
233
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
234
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
235
				if(!empty($item['type']))
236
					$itemtype = $item['type'];
237
				else
238
					$itemtype = "text";
239
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
240
			}
241
		}
242
	}
243
	$custoptionsv6 = "";
244
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {	
245
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
246
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
247
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
248
			}
249
		}
250
	}
251

    
252
	$dhcpdconf = <<<EOD
253
	
254
option domain-name "{$syscfg['domain']}";
255
option ldap-server code 95 = text;
256
option domain-search-list code 119 = text;
257
{$custoptions}
258
default-lease-time 7200;
259
max-lease-time 86400;
260
log-facility local7;
261
ddns-update-style none;
262
one-lease-per-client true;
263
deny duplicates;
264
ping-check true;
265

    
266
EOD;
267

    
268
	$dhcpdv6conf = <<<EOD
269
	
270
option domain-name "{$syscfg['domain']}";
271
option ldap-server code 95 = text;
272
option domain-search-list code 119 = text;
273
{$custoptions}
274
default-lease-time 7200;
275
max-lease-time 86400;
276
log-facility local7;
277
ddns-update-style none;
278
one-lease-per-client true;
279
deny duplicates;
280
ping-check true;
281

    
282
EOD;
283

    
284
	if(!isset($dhcpifconf['disableauthoritative']))
285
		$dhcpdconf .= "authoritative;\n";
286
	if(!isset($dhcpv6ifconf['disableauthoritative']))
287
		$dhcpdv6conf .= "authoritative;\n";
288

    
289
	if(isset($dhcpifconf['alwaysbroadcast'])) 
290
		$dhcpdconf .= "always-broadcast on\n";
291
	if(isset($dhcpv6ifconf['alwaysbroadcast'])) 
292
		$dhcpdv6conf .= "always-broadcast on\n";
293

    
294
	$dhcpdifs = array();
295
	$dhcpdv6ifs = array();
296

    
297
	/*    loop through and determine if we need to setup
298
	 *    failover peer "bleh" entries
299
	 */
300
	$dhcpnum = 0;
301
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
302

    
303
		interfaces_staticarp_configure($dhcpif);
304

    
305
		if (!isset($dhcpifconf['enable']))
306
			continue;
307

    
308
		if($dhcpifconf['failover_peerip'] <> "") {
309
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
310
			$intip = find_interface_ip($int);
311
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
312
			/*
313
			 *    yep, failover peer is defined.
314
			 *    does it match up to a defined vip?
315
			 */
316
			$skew = 110;
317
			$a_vip = &$config['virtualip']['vip'];
318
			if(is_array($a_vip)) {
319
				foreach ($a_vip as $vipent) {
320
					if($int == $real_dhcpif) {
321
						/* this is the interface! */
322
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
323
							$skew = 0;
324
					}
325
				}
326
			} else {
327
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
328
			}
329
			if($skew > 10) {
330
				$type = "secondary";
331
				$dhcpdconf_pri  = "mclt 600;\n";
332
				$my_port = "520";
333
				$peer_port = "519";
334
			} else {
335
				$my_port = "519";
336
				$peer_port = "520";
337
				$type = "primary";
338
				$dhcpdconf_pri  = "split 128;\n";
339
				$dhcpdconf_pri .= "  mclt 600;\n";
340
			}
341
			$dhcpdconf .= <<<EOPP
342
failover peer "dhcp{$dhcpnum}" {
343
  {$type};
344
  address {$intip};
345
  port {$my_port};
346
  peer address {$dhcpifconf['failover_peerip']};
347
  peer port {$peer_port};
348
  max-response-delay 10;
349
  max-unacked-updates 10;
350
  {$dhcpdconf_pri}
351
  load balance max seconds 3;
352
}
353

    
354
EOPP;
355
		$dhcpnum++;
356
		}
357
	}
358
	$dhcpv6num = 0;
359
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
360

    
361
		interfaces_staticarp_configure($dhcpv6if);
362

    
363
		if (!isset($dhcpv6ifconf['enable']))
364
			continue;
365

    
366
		if($dhcpv6ifconf['failover_peerip'] <> "") {
367
			$intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']);
368
			$intipv6 = find_interface_ipv6($intv6);
369
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
370
			/*
371
			 *    yep, failover peer is defined.
372
			 *    does it match up to a defined vip?
373
			 */
374
			$skew = 110;
375
			$a_vip = &$config['virtualip']['vip'];
376
			if(is_array($a_vip)) {
377
				foreach ($a_vip as $vipent) {
378
					if($intv6 == $real_dhcpv6if) {
379
						/* this is the interface! */
380
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
381
							$skew = 0;
382
					}
383
				}
384
			} else {
385
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
386
			}
387
			if($skew > 10) {
388
				$typev6 = "secondary";
389
				$dhcpdv6conf_pri  = "mclt 600;\n";
390
				$my_portv6 = "520";
391
				$peer_portv6 = "519";
392
			} else {
393
				$my_portv6 = "519";
394
				$peer_portv6 = "520";
395
				$typev6 = "primary";
396
				$dhcpdv6conf_pri  = "split 128;\n";
397
				$dhcpdv6conf_pri .= "  mclt 600;\n";
398
			}
399
			$dhcpdv6conf .= <<<EOPP
400
failover peer "dhcpv6{$dhcpv6num}" {
401
  {$typev6};
402
  address {$intipv6};
403
  port {$my_portv6};
404
  peer address {$dhcpv6ifconf['failover_peerip']};
405
  peer port {$peer_portv6};
406
  max-response-delay 10;
407
  max-unacked-updates 10;
408
  {$dhcpdv6conf_pri}
409
  load balance max seconds 3;
410
}
411

    
412
EOPP;
413
		$dhcpv6num++;
414
		}
415
	}
416

    
417
	$dhcpnum = 0;
418

    
419
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
420

    
421
		$ifcfg = $config['interfaces'][$dhcpif];
422

    
423
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
424
			continue;
425
		$ifcfgip = get_interface_ip($dhcpif);
426
		$ifcfgsn = get_interface_subnet($dhcpif);
427
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
428
		$subnetmask = gen_subnet_mask($ifcfgsn);
429

    
430
		if (!is_ipaddr($subnet))
431
			continue;
432

    
433
		if($is_olsr_enabled == true)
434
			if($dhcpifconf['netmask'])
435
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
436

    
437
		$dnscfg = "";
438

    
439
		if ($dhcpifconf['domain']) {
440
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
441
		}
442
		
443
    		if($dhcpifconf['domainsearchlist'] <> "") {
444
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
445
    		}
446

    
447
		if (isset($dhcpifconf['ddnsupdate'])) {
448
			if($dhcpifconf['ddnsdomain'] <> "") {
449
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
450
			}
451
			$dnscfg .= "	ddns-update-style interim;\n";
452
		}
453

    
454
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
455
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
456
		} else if (isset($config['dnsmasq']['enable'])) {
457
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
458
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
459
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
460
		}
461

    
462
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
463
		$dhcpdconf .= "	pool {\n";
464

    
465
		/* is failover dns setup? */
466
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
467
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
468
			if($dhcpifconf['dnsserver'][1] <> "")
469
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
470
			$dhcpdconf .= ";\n";
471
		}
472

    
473
		if($dhcpifconf['failover_peerip'] <> "")
474
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
475

    
476
		if (isset($dhcpifconf['denyunknown']))
477
		   $dhcpdconf .= "		deny unknown clients;\n";
478

    
479
		if ($dhcpifconf['gateway'])
480
			$routers = $dhcpifconf['gateway'];
481
		else
482
			$routers = $ifcfgip;
483

    
484
		if($dhcpifconf['failover_peerip'] <> "") {
485
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
486
			$dhcpnum++;
487
		}
488

    
489
		$dhcpdconf .= <<<EOD
490
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
491
	}
492
	option routers {$routers};
493
$dnscfg
494

    
495
EOD;
496
    		// default-lease-time
497
		if ($dhcpifconf['defaultleasetime'])
498
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
499

    
500
		// max-lease-time
501
		if ($dhcpifconf['maxleasetime'])
502
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
503

    
504
		// netbios-name*
505
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
506
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
507
			$dhcpdconf .= "	option netbios-node-type 8;\n";
508
		}
509

    
510
		// ntp-servers
511
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
512
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
513

    
514
		// tftp-server-name
515
		if ($dhcpifconf['tftp'] <> "")
516
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
517

    
518
		// Handle option, number rowhelper values
519
		$dhcpdconf .= "\n";
520
		if($dhcpifconf['numberoptions']['item']) {
521
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
522
				if(empty($item['type']) || $item['type'] == "text")
523
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
524
				else
525
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
526
			}
527
		}
528

    
529
		// ldap-server
530
		if ($dhcpifconf['ldap'] <> "")
531
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
532

    
533
		// net boot information
534
		if(isset($dhcpifconf['netboot'])) {
535
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
536
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
537
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
538
			}
539
			if ($dhcpifconf['rootpath'] <> "") {
540
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
541
      		}
542
		}
543
		
544
		$dhcpdconf .= <<<EOD
545
}
546

    
547
EOD;
548

    
549
		/* add static mappings */
550
		if (is_array($dhcpifconf['staticmap'])) {
551

    
552
			$i = 0;
553
			foreach ($dhcpifconf['staticmap'] as $sm) {
554
				$dhcpdconf .= <<<EOD
555
host s_{$dhcpif}_{$i} {
556
	hardware ethernet {$sm['mac']};
557

    
558
EOD;
559
				if ($sm['ipaddr'])
560
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
561

    
562
				if ($sm['hostname']) {
563
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
564
					$dhhostname = str_replace(".", "_", $dhhostname);
565
					$dhcpdconf .= "	option host-name {$dhhostname};\n";
566
				}
567
				if ($sm['netbootfile'])
568
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
569

    
570
				$dhcpdconf .= "}\n";
571
				$i++;
572
			}
573
		}
574

    
575
		$dhcpdifs[] = get_real_interface($dhcpif);
576
	}
577

    
578
	$dhcpv6num = 0;
579
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
580

    
581
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
582

    
583
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
584
			continue;
585
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
586
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
587
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
588
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
589

    
590
		if($is_olsr_enabled == true)
591
			if($dhcpv6ifconf['netmask'])
592
				$subnetmask = gen_subnet_mask($dhcpv6ifconf['netmask']);
593

    
594
		$dnscfgv6 = "";
595

    
596
		if ($dhcpv6ifconf['domain']) {
597
			$dnscfgv6 .= "	option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
598
		}
599
		
600
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
601
			$dnscfgv6 .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
602
    		}
603

    
604
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
605
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
606
				$dnscfgv6 .= "	ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
607
			}
608
			$dnscfgv6 .= "	ddns-update-style interim;\n";
609
		}
610

    
611
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
612
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
613
		} else if (isset($config['dnsmasq']['enable'])) {
614
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
615
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
616
			$dns_arrv6 = array();
617
			foreach($syscfg['dnsserver'] as $dnsserver) {
618
				if(is_ipaddrv6($dnsserver)) {
619
					$dns_arrv6[] = $dnsserver;
620
				}
621
			}
622
			if(!empty($dns_arrv6))
623
				$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dns_arrv6) . ";";
624
		}
625

    
626
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
627
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
628

    
629
		/* is failover dns setup? */
630
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
631
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
632
			if($dhcpv6ifconf['dnsserver'][1] <> "")
633
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
634
			$dhcpdv6conf .= ";\n";
635
		}
636

    
637
		if($dhcpv6ifconf['failover_peerip'] <> "")
638
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
639

    
640
		if (isset($dhcpv6ifconf['denyunknown']))
641
		   $dhcpdv6conf .= "		deny unknown clients;\n";
642

    
643
		if ($dhcpv6ifconf['gateway'])
644
			$routersv6 = $dhcpv6ifconf['gateway'];
645
		else
646
			$routersv6 = $ifcfgipv6;
647

    
648
		if($dhcpv6ifconf['failover_peerip'] <> "") {
649
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
650
			$dhcpv6num++;
651
		}
652

    
653
		$dhcpdv6conf .= <<<EOD
654
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
655
	# Not supported in IPv6; option dhcp6.routers {$routersv6};
656
$dnscfgv6
657

    
658
EOD;
659
    		// default-lease-time
660
		if ($dhcpv6ifconf['defaultleasetime'])
661
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
662

    
663
		// max-lease-time
664
		if ($dhcpv6ifconf['maxleasetime'])
665
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
666

    
667
		// ntp-servers
668
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0])
669
			$dhcpdv6conf .= "	option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
670

    
671
		// tftp-server-name
672
		if ($dhcpv6ifconf['tftp'] <> "")
673
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
674

    
675
		// Handle option, number rowhelper values
676
		$dhcpdv6conf .= "\n";
677
		if($dhcpv6ifconf['numberoptions']['item']) {
678
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
679
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
680
			}
681
		}
682

    
683
		// ldap-server
684
		if ($dhcpv6ifconf['ldap'] <> "")
685
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
686

    
687
		// net boot information
688
		if(isset($dhcpv6ifconf['netboot'])) {
689
			if (($dhcpv6ifconf['next-server'] <> "") && ($dhcpv6ifconf['filename'] <> "")) {
690
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['next-server']};\n";
691
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
692
			}
693
			if ($dhcpv6ifconf['rootpath'] <> "") {
694
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
695
      		}
696
	}
697
		
698
		$dhcpdv6conf .= <<<EOD
699
}
700
EOD;
701

    
702
		/* add static mappings */
703
		/* Does not work for IPv6
704
		/* You can not use a hardware parameter for DHCPv6 hosts
705
		/* Needs to be figured out
706
		if (is_array($dhcpv6ifconf['staticmap'])) {
707

    
708
			$i = 0;
709
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
710
				$dhcpdv6conf .= <<<EOD
711
host s_{$dhcpv6if}_{$i} {
712
	hardware ethernet {$sm['mac']};
713

    
714
EOD;
715
				if ($sm['ipaddr'])
716
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddr']};\n";
717

    
718
				if ($sm['hostname']) {
719
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
720
					$dhhostname = str_replace(".", "_", $dhhostname);
721
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
722
				}
723
				if ($sm['netbootfile'])
724
					$dhcpdv6conf .= "	filename \"{$sm['netbootfile']}\";\n";
725

    
726
				$dhcpdv6conf .= "}\n";
727
				$i++;
728
			}
729
		}
730
		*/
731
		
732
		if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") {
733
			$realif = escapeshellcmd(get_real_interface($dhcpv6if));
734
			$dhcpdv6ifs[] = $realif;
735
			/* Create link local address for bridges */
736
			if(stristr("$realif", "bridge")) {
737
				mwexec("$ifconfig {$realif} inet6 fe80::/64 eui64");
738
			}
739
		}
740
	}
741

    
742
	fwrite($fd, $dhcpdconf);
743
	fclose($fd);
744
	fwrite($fdv6, $dhcpdv6conf);
745
	fclose($fdv6);
746

    
747
	/* create an empty leases database */
748
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
749
	touch("{$g['varrun_path']}/dhcpd.pid");
750
	/* create an empty leases v6 database */
751
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
752
	touch("{$g['varrun_path']}/dhcpdv6.pid");
753
	
754

    
755
	/* fire up dhcpd in a chroot */
756
	if(count($dhcpdifs) > 0) {
757
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf " .
758
			join(" ", $dhcpdifs));
759
	}
760

    
761
	if(count($dhcpdv6ifs) > 0) {
762
		mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf " .
763
			join(" ", $dhcpdv6ifs));
764
		mwexec("/usr/sbin/rtadvd " . join(" ", $dhcpdv6ifs));
765
	}
766

    
767
	/* start ipv6 route advertising if required */
768
	services_rtadvd_configure();
769

    
770
	if ($g['booting']) {
771
		print "done.\n";
772
	}
773

    
774
	return 0;
775
}
776

    
777
function services_igmpproxy_configure() {
778
        global $config, $g;
779

    
780
        /* kill any running igmpproxy */
781
        killbyname("igmpproxy");
782

    
783
	if (!is_array($config['igmpproxy']['igmpentry']))
784
		return 1;
785

    
786
        $iflist = get_configured_interface_list();
787

    
788
        $igmpconf = <<<EOD
789

    
790
##------------------------------------------------------
791
## Enable Quickleave mode (Sends Leave instantly)
792
##------------------------------------------------------
793
quickleave
794

    
795
EOD;
796

    
797
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
798
                unset($iflist[$igmpcf['ifname']]);
799
                $realif = get_real_interface($igmpcf['ifname']);
800
                if (empty($igmpcf['threshold']))
801
                        $threshld = 1;
802
                else
803
                        $threshld = $igmpcf['threshold'];
804
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
805

    
806
                if ($igmpcf['address'] <> "") {
807
                        $item = explode(" ", $igmpcf['address']);
808
                        foreach($item as $iww)
809
                                $igmpconf .= "altnet {$iww}\n";
810
                }
811
                $igmpconf .= "\n";
812
        }
813
        foreach ($iflist as $ifn) {
814
                $realif = get_real_interface($ifn);
815
                $igmpconf .= "phyint {$realif} disabled\n";
816
        }
817

    
818
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
819
        if (!$igmpfl) {
820
                log_error("Could not write Igmpproxy configuration file!");
821
                return;
822
        }
823
        fwrite($igmpfl, $igmpconf);
824
        fclose($igmpfl);
825

    
826
        mwexec("/usr/local/sbin/igmpproxy -c " . $g['tmp_path'] . "/igmpproxy.conf");
827
        log_error("Started Igmpproxy service sucsesfully.");
828

    
829
        return 0;
830
}
831

    
832
function interfaces_staticarp_configure($if) {
833
	global $config, $g;
834
	if(isset($config['system']['developerspew'])) {
835
		$mt = microtime();
836
		echo "interfaces_staticarp_configure($if) being called $mt\n";
837
	}
838

    
839
        $ifcfg = $config['interfaces'][$if];
840

    
841
	if (empty($if) || empty($ifcfg['if']))
842
		return 0;
843

    
844
        /* Enable staticarp, if enabled */
845
        if(isset($config['dhcpd'][$if]['staticarp'])) {
846
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
847
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
848
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
849

    
850
                        foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
851
                                mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
852

    
853
                        }
854

    
855
                }
856
        } else {
857
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
858
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
859
        }
860

    
861
        return 0;
862
}
863

    
864
function services_dhcrelay_configure() {
865
	global $config, $g;
866
	if(isset($config['system']['developerspew'])) {
867
		$mt = microtime();
868
		echo "services_dhcrelay_configure() being called $mt\n";
869
	}
870

    
871
	/* kill any running dhcrelay */
872
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
873

    
874
	$dhcrelaycfg =& $config['dhcrelay'];
875

    
876
	/* DHCPRelay enabled on any interfaces? */
877
	if (!isset($dhcrelaycfg['enable']))
878
		return 0;
879

    
880
	if ($g['booting'])
881
		echo "Starting DHCP relay service...";
882
	else
883
		sleep(1);
884

    
885
	$iflist = get_configured_interface_list();
886

    
887
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
888
	foreach ($dhcifaces as $dhcrelayif) {
889
		if (!isset($iflist[$dhcrelayif]) ||
890
			link_interface_to_bridge($dhcrelayif))
891
			continue;
892

    
893
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
894
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
895
	}
896

    
897
	/* 
898
	 * In order for the relay to work, it needs to be active
899
	 * on the interface in which the destination server sits.
900
	 */
901
	$srvips = explode(",", $dhcrelaycfg['server']);
902
	foreach ($srvips as $srcidx => $srvip) {
903
		unset($destif);
904
		foreach ($iflist as $ifname) {
905
			$subnet = get_interface_ip($ifname);
906
			if (!is_ipaddr($subnet))
907
				continue;
908
			$subnet .=  "/" . get_interface_subnet($ifname);
909
			if (ip_in_subnet($srvip, $subnet)) {
910
				$destif = get_real_interface($ifname);
911
				break;
912
			}
913
		}
914
		if (!isset($destif)) {
915
			if (is_array($config['staticroutes']['route'])) {
916
				foreach ($config['staticroutes']['route'] as $rtent) {
917
					if (ip_in_subnet($srvip, $rtent['network'])) {
918
						$a_gateways = return_gateways_array(true);
919
						$destif = $a_gateways[$rtent['gateway']]['interface'];
920
						break;
921
					}
922
				}
923
			}
924
		}
925

    
926
		if (!isset($destif)) {
927
			/* Create a array from the existing route table */
928
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
929
        		array_shift($route_str);
930
        		array_shift($route_str);
931
        		array_shift($route_str);
932
        		array_shift($route_str);
933
        		$route_arr = array();
934
        		foreach($route_str as $routeline) {
935
                		$items = preg_split("/[ ]+/i", $routeline);
936
				if (ip_in_subnet($srvip, $items[0])) {
937
					$destif = trim($items[2]);
938
					break;
939
				}
940
        		}
941
		}
942
	
943
		if (!isset($destif)) {
944
			if (is_array($config['gateways']['gateway_item'])) {
945
				foreach ($config['gateways']['gateway_item'] as $gateway) {
946
					if (isset($gateway['defaultgw'])) {
947
						$a_gateways = return_gateways_array(true);
948
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
949
						break;
950
					}		
951
				}
952
			} else
953
				$destif = get_real_interface("wan");
954
		}
955

    
956
		if (!empty($destif))
957
			$dhcrelayifs[] = $destif;
958
	}
959
	$dhcrelayifs = array_unique($dhcrelayifs);
960

    
961
	/* fire up dhcrelay */
962
	if (empty($dhcrelayifs)) {
963
		log_error("No suitable interface found for running dhcrelay!");
964
		return; /* XXX */
965
	}
966

    
967
	$cmd = "/usr/local/sbin/dhcrelay -i " .  implode(" -i ", $dhcrelayifs);
968

    
969
	if (isset($dhcrelaycfg['agentoption']))
970
		$cmd .=  " -a -m replace";
971

    
972
	$cmd .= " " . implode(" ", $srvips);
973
	mwexec($cmd);
974

    
975
	return 0;
976
}
977

    
978
function services_dyndns_configure_client($conf) {
979

    
980
	if (!isset($conf['enable']))
981
		return;
982

    
983
	/* load up the dyndns.class */
984
	require_once("dyndns.class");
985

    
986
	log_error("DynDns: Running updatedns()");
987

    
988
	$dns = new updatedns($dnsService = $conf['type'],
989
		$dnsHost = $conf['host'],
990
		$dnsUser = $conf['username'],
991
		$dnsPass = $conf['password'],
992
		$dnsWilcard = $conf['wildcard'],
993
		$dnsMX = $conf['mx'], 
994
		$dnsIf = "{$conf['interface']}");
995

    
996
}
997

    
998
function services_dyndns_configure($int = "") {
999
	global $config, $g;
1000
	if(isset($config['system']['developerspew'])) {
1001
		$mt = microtime();
1002
		echo "services_dyndns_configure() being called $mt\n";
1003
	}
1004

    
1005
	$dyndnscfg = $config['dyndnses']['dyndns'];
1006

    
1007
	if (is_array($dyndnscfg)) {
1008
		if ($g['booting']) 
1009
			echo "Starting DynDNS clients...";
1010

    
1011
		foreach ($dyndnscfg as $dyndns) {
1012
			if (!empty($int) && $int != $dyndns['interface'])
1013
				continue;
1014

    
1015
			services_dyndns_configure_client($dyndns);
1016

    
1017
			sleep(1);
1018
		}
1019

    
1020
		if ($g['booting'])
1021
			echo "done.\n";
1022
	}
1023

    
1024
	return 0;
1025
}
1026

    
1027
function services_dnsmasq_configure() {
1028
	global $config, $g;
1029
	$return = 0;
1030
	
1031
	if(isset($config['system']['developerspew'])) {
1032
		$mt = microtime();
1033
		echo "services_dnsmasq_configure() being called $mt\n";
1034
	}
1035

    
1036
	/* kill any running dnsmasq */
1037
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
1038

    
1039
	if (isset($config['dnsmasq']['enable'])) {
1040

    
1041
		if ($g['booting'])
1042
			echo "Starting DNS forwarder...";
1043
		else
1044
			sleep(1);
1045

    
1046
		/* generate hosts file */
1047
		if(system_hosts_generate()!=0)
1048
			$return = 1;
1049

    
1050
		$args = "";
1051

    
1052
		if (isset($config['dnsmasq']['regdhcp'])) {
1053
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1054
		}
1055
		
1056
		/* Setup forwarded domains */
1057
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1058
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1059
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1060
			}
1061
		}
1062

    
1063
		/* Allow DNS Rebind for forwarded domains */
1064
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1065
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1066
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1067
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1068
				}
1069
			}
1070
		}
1071

    
1072
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1073
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1074

    
1075
		/* run dnsmasq */
1076
		mwexec("/usr/local/sbin/dnsmasq --local-ttl 1 --all-servers {$dns_rebind} --dns-forward-max=5000 --cache-size=10000 {$args}");
1077

    
1078
		if ($g['booting'])
1079
			echo "done.\n";
1080
	}
1081

    
1082
	if (!$g['booting']) {
1083
		if(services_dhcpd_configure()!=0)
1084
			$return = 1;
1085
	}
1086

    
1087
	return $return;
1088
}
1089

    
1090
function services_snmpd_configure() {
1091
	global $config, $g;
1092
	if(isset($config['system']['developerspew'])) {
1093
		$mt = microtime();
1094
		echo "services_snmpd_configure() being called $mt\n";
1095
	}
1096

    
1097
	/* kill any running snmpd */
1098
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1099
	sleep(2);
1100
	if(is_process_running("bsnmpd")) 
1101
		mwexec("/usr/bin/killall bsnmpd", true);
1102

    
1103
	if (isset($config['snmpd']['enable'])) {
1104

    
1105
		if ($g['booting'])
1106
			echo "Starting SNMP daemon... ";
1107

    
1108
		/* generate snmpd.conf */
1109
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1110
		if (!$fd) {
1111
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
1112
			return 1;
1113
		}
1114

    
1115

    
1116
		$snmpdconf = <<<EOD
1117
location := "{$config['snmpd']['syslocation']}"
1118
contact := "{$config['snmpd']['syscontact']}"
1119
read := "{$config['snmpd']['rocommunity']}"
1120

    
1121
EOD;
1122

    
1123
/* No docs on what write strings do there for disable for now.
1124
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1125
		    $snmpdconf .= <<<EOD
1126
# write string
1127
write := "{$config['snmpd']['rwcommunity']}"
1128

    
1129
EOD;
1130
		}
1131
*/
1132

    
1133

    
1134
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1135
		    $snmpdconf .= <<<EOD
1136
# SNMP Trap support.
1137
traphost := {$config['snmpd']['trapserver']}
1138
trapport := {$config['snmpd']['trapserverport']}
1139
trap := "{$config['snmpd']['trapstring']}"
1140

    
1141

    
1142
EOD;
1143
		}
1144

    
1145

    
1146
		$snmpdconf .= <<<EOD
1147
system := 1     # pfSense
1148
%snmpd
1149
begemotSnmpdDebugDumpPdus       = 2
1150
begemotSnmpdDebugSyslogPri      = 7
1151
begemotSnmpdCommunityString.0.1 = $(read)
1152

    
1153
EOD;
1154

    
1155
/* No docs on what write strings do there for disable for now.
1156
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1157
		    $snmpdconf .= <<<EOD
1158
begemotSnmpdCommunityString.0.2 = $(write)
1159

    
1160
EOD;
1161
		}
1162
*/
1163

    
1164

    
1165
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1166
		    $snmpdconf .= <<<EOD
1167
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1168
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1169
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1170

    
1171
EOD;
1172
		}
1173

    
1174

    
1175
		$snmpdconf .= <<<EOD
1176
begemotSnmpdCommunityDisable    = 1
1177

    
1178
EOD;
1179

    
1180
		if(isset($config['snmpd']['bindlan'])) {
1181
			$bind_to_ip = get_interface_ip("lan");
1182
		} else {
1183
			$bind_to_ip = "0.0.0.0";
1184
		}
1185

    
1186
		if(is_port( $config['snmpd']['pollport'] )) {
1187
		    $snmpdconf .= <<<EOD
1188
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1189

    
1190
EOD;
1191

    
1192
		}
1193

    
1194
		$snmpdconf .= <<<EOD
1195
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1196
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1197

    
1198
# These are bsnmp macros not php vars.
1199
sysContact      = $(contact)
1200
sysLocation     = $(location)
1201
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1202

    
1203
snmpEnableAuthenTraps = 2
1204

    
1205
EOD;
1206

    
1207
		if (is_array( $config['snmpd']['modules'] )) {
1208
		    if(isset($config['snmpd']['modules']['mibii'])) {
1209
			$snmpdconf .= <<<EOD
1210
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1211

    
1212
EOD;
1213
		    }
1214

    
1215
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1216
			$snmpdconf .= <<<EOD
1217
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1218
%netgraph
1219
begemotNgControlNodeName = "snmpd"
1220

    
1221
EOD;
1222
		    }
1223

    
1224
		    if(isset($config['snmpd']['modules']['pf'])) {
1225
			$snmpdconf .= <<<EOD
1226
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1227

    
1228
EOD;
1229
		    }
1230

    
1231
		    if(isset($config['snmpd']['modules']['hostres'])) {
1232
			$snmpdconf .= <<<EOD
1233
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1234

    
1235
EOD;
1236
		    }
1237
		    if(isset($config['snmpd']['modules']['bridge'])) {
1238
			$snmpdconf .= <<<EOD
1239
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1240
# config must end with blank line
1241

    
1242

    
1243
EOD;
1244
		    }
1245
		}
1246

    
1247
		fwrite($fd, $snmpdconf);
1248
		fclose($fd);
1249

    
1250
		if (isset($config['snmpd']['bindlan'])) {
1251
			$bindlan = "";
1252
		}
1253

    
1254
		/* run bsnmpd */
1255
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1256
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1257

    
1258
		if ($g['booting'])
1259
			echo "done.\n";
1260
	}
1261

    
1262
	return 0;
1263
}
1264

    
1265
function services_dnsupdate_process($int = "") {
1266
	global $config, $g;
1267
	if(isset($config['system']['developerspew'])) {
1268
		$mt = microtime();
1269
		echo "services_dnsupdate_process() being called $mt\n";
1270
	}
1271

    
1272
	/* Dynamic DNS updating active? */
1273
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1274
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1275
			if (!isset($dnsupdate['enable']))
1276
				continue;
1277
			if (!empty($int) && $int != $dnsupdate['interface'])
1278
				continue;
1279

    
1280
			/* determine interface name */
1281
			$if = get_real_interface($dnsupdate['interface']);
1282
			$wanip = get_interface_ip($dnsupdate['interface']);
1283
			if ($wanip) {
1284

    
1285
				$keyname = $dnsupdate['keyname'];
1286
				/* trailing dot */
1287
				if (substr($keyname, -1) != ".")
1288
					$keyname .= ".";
1289

    
1290
				$hostname = $dnsupdate['host'];
1291
				/* trailing dot */
1292
				if (substr($hostname, -1) != ".")
1293
					$hostname .= ".";
1294

    
1295
				/* write private key file
1296
				   this is dumb - public and private keys are the same for HMAC-MD5,
1297
				   but nsupdate insists on having both */
1298
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1299
				$privkey .= <<<EOD
1300
Private-key-format: v1.2
1301
Algorithm: 157 (HMAC)
1302
Key: {$dnsupdate['keydata']}
1303

    
1304
EOD;
1305
				fwrite($fd, $privkey);
1306
				fclose($fd);
1307

    
1308
				/* write public key file */
1309
				if ($dnsupdate['keytype'] == "zone") {
1310
					$flags = 257;
1311
					$proto = 3;
1312
				} else if ($dnsupdate['keytype'] == "host") {
1313
					$flags = 513;
1314
					$proto = 3;
1315
				} else if ($dnsupdate['keytype'] == "user") {
1316
					$flags = 0;
1317
					$proto = 2;
1318
				}
1319

    
1320
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.key", "w");
1321
				fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n");
1322
				fclose($fd);
1323

    
1324
				/* generate update instructions */
1325
				$upinst = "";
1326
				if (!empty($dnsupdate['server']))
1327
					$upinst .= "server {$dnsupdate['server']}\n";
1328
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1329
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1330
				$upinst .= "\n";	/* mind that trailing newline! */
1331

    
1332
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1333
				fwrite($fd, $upinst);
1334
				fclose($fd);
1335

    
1336
				/* invoke nsupdate */
1337
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1338
				if (isset($dnsupdate['usetcp']))
1339
					$cmd .= " -v";
1340
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1341
	
1342
				mwexec_bg($cmd);
1343
			}
1344
		}
1345
	}
1346

    
1347
	return 0;
1348
}
1349

    
1350
function setup_wireless_olsr() {
1351
	global $config, $g;
1352
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1353
		return;
1354
	if(isset($config['system']['developerspew'])) {
1355
		$mt = microtime();
1356
		echo "setup_wireless_olsr($interface) being called $mt\n";
1357
	}
1358
	conf_mount_rw();
1359
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1360
		$olsr_enable = $olsrd['enable'];
1361
		if($olsr_enable <> "on")
1362
			return;
1363
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1364

    
1365
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1366
			$enableannounce .= "\nHna4\n";
1367
			$enableannounce .= "{\n";
1368
		if($olsrd['announcedynamicroute'])
1369
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1370
		if($olsrd['enableannounce'] == "on")
1371
			$enableannounce .= "0.0.0.0 0.0.0.0";
1372
			$enableannounce .= "\n}\n";
1373
		} else {
1374
			$enableannounce = "";
1375
		}
1376

    
1377
		$olsr .= <<<EODA
1378
#
1379
# olsr.org OLSR daemon config file
1380
#
1381
# Lines starting with a # are discarded
1382
#
1383
# This file was generated by setup_wireless_olsr() in services.inc
1384
#
1385

    
1386
# This file is an example of a typical
1387
# configuration for a mostly static
1388
# network(regarding mobility) using
1389
# the LQ extention
1390

    
1391
# Debug level(0-9)
1392
# If set to 0 the daemon runs in the background
1393

    
1394
DebugLevel	2
1395

    
1396
# IP version to use (4 or 6)
1397

    
1398
IpVersion	4
1399

    
1400
# Clear the screen each time the internal state changes
1401

    
1402
ClearScreen     yes
1403

    
1404
{$enableannounce}
1405

    
1406
# Should olsrd keep on running even if there are
1407
# no interfaces available? This is a good idea
1408
# for a PCMCIA/USB hotswap environment.
1409
# "yes" OR "no"
1410

    
1411
AllowNoInt	yes
1412

    
1413
# TOS(type of service) value for
1414
# the IP header of control traffic.
1415
# If not set it will default to 16
1416

    
1417
#TosValue	16
1418

    
1419
# The fixed willingness to use(0-7)
1420
# If not set willingness will be calculated
1421
# dynamically based on battery/power status
1422
# if such information is available
1423

    
1424
#Willingness    	4
1425

    
1426
# Allow processes like the GUI front-end
1427
# to connect to the daemon.
1428

    
1429
IpcConnect
1430
{
1431
     # Determines how many simultaneously
1432
     # IPC connections that will be allowed
1433
     # Setting this to 0 disables IPC
1434

    
1435
     MaxConnections  0
1436

    
1437
     # By default only 127.0.0.1 is allowed
1438
     # to connect. Here allowed hosts can
1439
     # be added
1440

    
1441
     Host            127.0.0.1
1442
     #Host            10.0.0.5
1443

    
1444
     # You can also specify entire net-ranges
1445
     # that are allowed to connect. Multiple
1446
     # entries are allowed
1447

    
1448
     #Net             192.168.1.0 255.255.255.0
1449
}
1450

    
1451
# Wether to use hysteresis or not
1452
# Hysteresis adds more robustness to the
1453
# link sensing but delays neighbor registration.
1454
# Used by default. 'yes' or 'no'
1455

    
1456
UseHysteresis	no
1457

    
1458
# Hysteresis parameters
1459
# Do not alter these unless you know
1460
# what you are doing!
1461
# Set to auto by default. Allowed
1462
# values are floating point values
1463
# in the interval 0,1
1464
# THR_LOW must always be lower than
1465
# THR_HIGH.
1466

    
1467
#HystScaling	0.50
1468
#HystThrHigh	0.80
1469
#HystThrLow	0.30
1470

    
1471

    
1472
# Link quality level
1473
# 0 = do not use link quality
1474
# 1 = use link quality for MPR selection
1475
# 2 = use link quality for MPR selection and routing
1476
# Defaults to 0
1477

    
1478
LinkQualityLevel	{$olsrd['enablelqe']}
1479

    
1480
# Link quality window size
1481
# Defaults to 10
1482

    
1483
LinkQualityWinSize	10
1484

    
1485
# Polling rate in seconds(float).
1486
# Default value 0.05 sec
1487

    
1488
Pollrate	0.05
1489

    
1490

    
1491
# TC redundancy
1492
# Specifies how much neighbor info should
1493
# be sent in TC messages
1494
# Possible values are:
1495
# 0 - only send MPR selectors
1496
# 1 - send MPR selectors and MPRs
1497
# 2 - send all neighbors
1498
#
1499
# defaults to 0
1500

    
1501
TcRedundancy	2
1502

    
1503
#
1504
# MPR coverage
1505
# Specifies how many MPRs a node should
1506
# try select to reach every 2 hop neighbor
1507
#
1508
# Can be set to any integer >0
1509
#
1510
# defaults to 1
1511

    
1512
MprCoverage	3
1513

    
1514
# Example plugin entry with parameters:
1515

    
1516
EODA;
1517

    
1518
if($olsrd['enablehttpinfo'] == "on") {
1519
	$olsr .= <<<EODB
1520

    
1521
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1522
{
1523
    PlParam     "port"   "{$olsrd['port']}"
1524
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1525
}
1526

    
1527
EODB;
1528

    
1529
}
1530

    
1531
if($olsrd['enabledsecure'] == "on") {
1532
	$olsr .= <<<EODC
1533

    
1534
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1535
{
1536
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1537
}
1538

    
1539
EODC;
1540

    
1541
}
1542

    
1543
if($olsrd['enabledyngw'] == "on") {
1544

    
1545
	/* unset default route, olsr auto negotiates */
1546
	mwexec("/sbin/route delete default");
1547

    
1548
	$olsr .= <<<EODE
1549

    
1550
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1551
{
1552
    # how often to look for a inet gw, in seconds
1553
    # defaults to 5 secs, if commented out
1554
    PlParam     "Interval"   "{$olsrd['polling']}"
1555

    
1556
    # if one or more IPv4 addresses are given, do a ping on these in
1557
    # descending order to validate that there is not only an entry in
1558
    # routing table, but also a real internet connection. If any of
1559
    # these addresses could be pinged successfully, the test was
1560
    # succesful, i.e. if the ping on the 1st address was successful,the
1561
    # 2nd won't be pinged
1562
    PlParam     "Ping"       "{$olsrd['ping']}"
1563
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1564
}
1565

    
1566
EODE;
1567

    
1568
}
1569

    
1570
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1571
	$interfaces = explode(',', $conf['iface_array']);
1572
	foreach($interfaces as $interface) {
1573
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1574
$olsr .= <<<EODAD
1575
Interface "{$realinterface}"
1576
{
1577

    
1578
    # Hello interval in seconds(float)
1579
    HelloInterval    2.0
1580

    
1581
    # HELLO validity time
1582
    HelloValidityTime	20.0
1583

    
1584
    # TC interval in seconds(float)
1585
    TcInterval        5.0
1586

    
1587
    # TC validity time
1588
    TcValidityTime	30.0
1589

    
1590
    # MID interval in seconds(float)
1591
    MidInterval	5.0
1592

    
1593
    # MID validity time
1594
    MidValidityTime	30.0
1595

    
1596
    # HNA interval in seconds(float)
1597
    HnaInterval	5.0
1598

    
1599
    # HNA validity time
1600
    HnaValidityTime 	30.0
1601

    
1602
    # When multiple links exist between hosts
1603
    # the weight of interface is used to determine
1604
    # the link to use. Normally the weight is
1605
    # automatically calculated by olsrd based
1606
    # on the characteristics of the interface,
1607
    # but here you can specify a fixed value.
1608
    # Olsrd will choose links with the lowest value.
1609

    
1610
    # Weight 0
1611

    
1612

    
1613
}
1614

    
1615
EODAD;
1616

    
1617
	}
1618
	break;
1619
}
1620
		fwrite($fd, $olsr);
1621
		fclose($fd);
1622
	}
1623

    
1624
	if(is_process_running("olsrd"))
1625
		mwexec("/usr/bin/killall olsrd", true);
1626

    
1627
	sleep(2);
1628

    
1629
	mwexec_bg("/usr/local/sbin/olsrd -f {$g['varetc_path']}/olsr.conf");
1630

    
1631
	conf_mount_ro();
1632
}
1633

    
1634
/* configure cron service */
1635
function configure_cron() {
1636
	global $g, $config;
1637

    
1638
	conf_mount_rw();
1639
	/* preserve existing crontab entries */
1640
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1641
	
1642
	for ($i = 0; $i < count($crontab_contents); $i++) {
1643
		$cron_item =& $crontab_contents[$i];
1644
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
1645
			array_splice($crontab_contents, $i - 1);
1646
			break;
1647
		}
1648
	}
1649
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
1650
	
1651
	
1652
	if (is_array($config['cron']['item'])) {
1653
		$crontab_contents .= "#\n";
1654
		$crontab_contents .= "# pfSense specific crontab entries\n";
1655
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1656
		$crontab_contents .= "#\n";
1657

    
1658
		foreach ($config['cron']['item'] as $item) {
1659
			$crontab_contents .= "\n{$item['minute']}\t";
1660
			$crontab_contents .= "{$item['hour']}\t";
1661
			$crontab_contents .= "{$item['mday']}\t";
1662
			$crontab_contents .= "{$item['month']}\t";
1663
			$crontab_contents .= "{$item['wday']}\t";
1664
			$crontab_contents .= "{$item['who']}\t";
1665
			$crontab_contents .= "{$item['command']}";
1666
		}
1667
    
1668
		$crontab_contents .= "\n#\n";
1669
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1670
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1671
		$crontab_contents .= "#\n\n";
1672
	}
1673
	
1674
	/* please maintain the newline at the end of file */
1675
	file_put_contents("/etc/crontab", $crontab_contents);
1676

    
1677
	/* do a HUP kill to force sync changes */
1678
	exec('/bin/pkill -HUP cron');
1679

    
1680
	conf_mount_ro();
1681
}
1682

    
1683
function upnp_action ($action) {
1684
	switch($action) {
1685
		case "start":
1686
			if (file_exists('/var/etc/miniupnpd.conf')) {
1687
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
1688
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
1689
			}
1690
			break;
1691
		case "stop":
1692
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
1693
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
1694
				mwexec('killall miniupnpd 2>/dev/null', true);
1695
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1696
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1697
			break;
1698
		case "restart":
1699
			upnp_action('stop');
1700
			upnp_action('start');
1701
			break;
1702
	}
1703
}
1704

    
1705
function upnp_start() {
1706
	global $config;
1707

    
1708
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1709
		return;
1710

    
1711
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1712
		echo "Starting UPnP service... ";
1713
		require_once('/usr/local/pkg/miniupnpd.inc');
1714
		sync_package_miniupnpd();
1715
		echo "done.\n";
1716
	}
1717
}
1718

    
1719
function install_cron_job($command, $active=false, $minute="0", $hour="*", $monthday="*", $month="*", $weekday="*", $who="root") {
1720
	global $config, $g;
1721

    
1722
	$is_installed = false;
1723

    
1724
	if(!$config['cron']['item'])
1725
		return;
1726

    
1727
	$x=0;
1728
	foreach($config['cron']['item'] as $item) {
1729
		if(strstr($item['command'], $command)) {
1730
			$is_installed = true;
1731
			break;
1732
		}
1733
		$x++;
1734
	}
1735

    
1736
	if($active) {
1737
		$cron_item = array();
1738
		$cron_item['minute'] = $minute;
1739
		$cron_item['hour'] = $hour;
1740
		$cron_item['mday'] = $monthday;
1741
		$cron_item['month'] = $month;
1742
		$cron_item['wday'] = $weekday;
1743
		$cron_item['who'] = $who;
1744
		$cron_item['command'] = $command;
1745
		if(!$is_installed) {
1746
			$config['cron']['item'][] = $cron_item;
1747
			write_config("Installed cron job for {$command}");
1748
		} else {
1749
			$config['cron']['item'][$x] = $cron_item;
1750
			write_config("Updated cron job for {$command}");
1751
		}
1752
	} else {
1753
		if(($is_installed == true) && ($x > 0)) {
1754
			unset($config['cron']['item'][$x]);
1755
			write_config("Remvoed cron job for {$command}");
1756
		}
1757
	}
1758
	configure_cron();
1759
}
1760

    
1761
?>
(44-44/61)