Project

General

Profile

Download (35.9 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	
39
	pfSense_MODULE:	utils
40
*/
41

    
42
function services_dhcpd_configure() {
43
	global $config, $g;
44
	
45
	if($g['services_dhcp_server_enable'] == false) 
46
		return;
47

    
48
	if(isset($config['system']['developerspew'])) {
49
		$mt = microtime();
50
		echo "services_dhcpd_configure($if) being called $mt\n";
51
	}
52
	
53
	/* kill any running dhcpd */
54
	if(is_process_running("dhcpd"))
55
		mwexec("killall dhcpd", true);
56

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

    
61
	/* if OLSRD is enabled, allow WAN to house DHCP. */
62
	if($config['installedpackages']['olsrd'])
63
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
64
				if($olsrd['enable'])
65
					$is_olsr_enabled = true;
66

    
67
	/* configure DHCPD chroot */
68
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
69
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
70
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
71
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
72
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
73
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
74
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
75
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");
76
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
77
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
78
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
79
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
80
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
81
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
82
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
83
	if(!trim($status))
84
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
85
	fclose($fd);
86
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
87

    
88
	if ($g['booting']) {
89
		if ($g['platform'] != "pfSense") {
90
			/* restore the leases, if we have them */
91
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
92
				$dhcprestore = "";
93
				$dhcpreturn = "";
94
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
95
				$dhcprestore = implode(" ", $dhcprestore);
96
				if($dhcpreturn <> 0) {
97
					log_error("DHCP leases restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
98
				}
99
			}
100
		}
101
	}
102

    
103
	$syscfg = $config['system'];
104
	$dhcpdcfg = $config['dhcpd'];
105
	$Iflist = get_configured_interface_list();
106
		
107
	if ($g['booting'])
108
		echo "Starting DHCP service...";
109
	else
110
		sleep(1);
111

    
112
	/* write dhcpd.conf */
113
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
114
	if (!$fd) {
115
		printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
116
		return 1;
117
	}
118

    
119
	$custoptions = "";
120
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
121
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
122
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
123
				if(!empty($item['type']))
124
					$itemtype = $item['type'];
125
				else
126
					$itemtype = "text";
127
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = {$itemtype};\n";
128
			}
129
		}
130
	}
131

    
132
	$dhcpdconf = <<<EOD
133
	
134
option domain-name "{$syscfg['domain']}";
135
option ldap-server code 95 = text;
136
option domain-search-list code 119 = text;
137
{$custoptions}
138
default-lease-time 7200;
139
max-lease-time 86400;
140
log-facility local7;
141
ddns-update-style none;
142
one-lease-per-client true;
143
deny duplicates;
144
ping-check true;
145

    
146
EOD;
147

    
148
	if(!isset($dhcpifconf['disableauthoritative']))
149
		$dhcpdconf .= "authoritative;\n";
150

    
151
	if(isset($dhcpifconf['alwaysbroadcast'])) 
152
		$dhcpdconf .= "always-broadcast on\n";
153

    
154
	$dhcpdifs = array();
155

    
156
	/*    loop through and determine if we need to setup
157
	 *    failover peer "bleh" entries
158
	 */
159
	$dhcpnum = 0;
160
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
161

    
162
		interfaces_staticarp_configure($dhcpif);
163

    
164
		if (!isset($dhcpifconf['enable']))
165
			continue;
166

    
167
		if($dhcpifconf['failover_peerip'] <> "") {
168
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
169
			$intip = find_interface_ip($int);
170
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
171
			/*
172
			 *    yep, failover peer is defined.
173
			 *    does it match up to a defined vip?
174
			 */
175
			$skew = 110;
176
			$a_vip = &$config['virtualip']['vip'];
177
			if(is_array($a_vip)) {
178
				foreach ($a_vip as $vipent) {
179
					if($int == $real_dhcpif) {
180
						/* this is the interface! */
181
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
182
							$skew = 0;
183
					}
184
				}
185
			} else {
186
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
187
			}
188
			if($skew > 10) {
189
				$type = "secondary";
190
				$dhcpdconf_pri  = "mclt 600;\n";
191
				$my_port = "520";
192
				$peer_port = "519";
193
			} else {
194
				$my_port = "519";
195
				$peer_port = "520";
196
				$type = "primary";
197
				$dhcpdconf_pri  = "split 128;\n";
198
				$dhcpdconf_pri .= "  mclt 600;\n";
199
			}
200
			$dhcpdconf .= <<<EOPP
201
failover peer "dhcp{$dhcpnum}" {
202
  {$type};
203
  address {$intip};
204
  port {$my_port};
205
  peer address {$dhcpifconf['failover_peerip']};
206
  peer port {$peer_port};
207
  max-response-delay 10;
208
  max-unacked-updates 10;
209
  {$dhcpdconf_pri}
210
  load balance max seconds 3;
211
}
212

    
213
EOPP;
214
		$dhcpnum++;
215
		}
216
	}
217

    
218
	$dhcpnum = 0;
219

    
220
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
221

    
222
		$ifcfg = $config['interfaces'][$dhcpif];
223

    
224
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
225
			continue;
226
		$ifcfgip = get_interface_ip($dhcpif);
227
		$ifcfgsn = get_interface_subnet($dhcpif);
228
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
229
		$subnetmask = gen_subnet_mask($ifcfgsn);
230

    
231
		if (!is_ipaddr($subnet))
232
			continue;
233

    
234
		if($is_olsr_enabled == true)
235
			if($dhcpifconf['netmask'])
236
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
237

    
238
		$dnscfg = "";
239

    
240
		if ($dhcpifconf['domain']) {
241
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
242
		}
243
		
244
    		if($dhcpifconf['domainsearchlist'] <> "") {
245
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
246
    		}
247

    
248
		if (isset($dhcpifconf['ddnsupdate'])) {
249
			if($dhcpifconf['ddnsdomain'] <> "") {
250
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
251
			}
252
			$dnscfg .= "	ddns-update-style interim;\n";
253
		}
254

    
255
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
256
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
257
		} else if (isset($config['dnsmasq']['enable'])) {
258
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
259
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
260
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
261
		}
262

    
263
		$dhcpdconf .= "subnet {$subnet} netmask {$subnetmask} {\n";
264
		$dhcpdconf .= "	pool {\n";
265

    
266
		/* is failover dns setup? */
267
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
268
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
269
			if($dhcpifconf['dnsserver'][1] <> "")
270
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
271
			$dhcpdconf .= ";\n";
272
		}
273

    
274
		if($dhcpifconf['failover_peerip'] <> "")
275
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
276

    
277
		if (isset($dhcpifconf['denyunknown']))
278
		   $dhcpdconf .= "		deny unknown-clients;\n";
279

    
280
		if ($dhcpifconf['gateway'])
281
			$routers = $dhcpifconf['gateway'];
282
		else
283
			$routers = $ifcfgip;
284

    
285
		if($dhcpifconf['failover_peerip'] <> "") {
286
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
287
			$dhcpnum++;
288
		}
289

    
290
		$dhcpdconf .= <<<EOD
291
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
292
	}
293
	option routers {$routers};
294
$dnscfg
295

    
296
EOD;
297
    
298
		// default-lease-time
299
		if ($dhcpifconf['defaultleasetime'])
300
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
301

    
302
		// max-lease-time
303
		if ($dhcpifconf['maxleasetime'])
304
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
305

    
306
		// netbios-name*
307
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
308
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
309
			$dhcpdconf .= "	option netbios-node-type 8;\n";
310
		}
311

    
312
		// ntp-servers
313
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
314
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
315

    
316
		// tftp-server-name
317
		if ($dhcpifconf['tftp'] <> "")
318
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
319

    
320
		// Handle option, number rowhelper values
321
		$dhcpdconf .= "\n";
322
		if($dhcpifconf['numberoptions']['item']) {
323
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
324
				if(empty($item['type']) || $item['type'] == "text")
325
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
326
				else
327
					$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} {$item['value']};\n";
328
			}
329
		}
330

    
331
		// ldap-server
332
		if ($dhcpifconf['ldap'] <> "")
333
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
334

    
335
		// net boot information
336
		if(isset($dhcpifconf['netboot'])) {
337
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
338
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
339
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
340
			}
341
			if ($dhcpifconf['rootpath'] <> "") {
342
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
343
      		}
344
		}
345
		
346
		$dhcpdconf .= <<<EOD
347
}
348

    
349
EOD;
350

    
351
		/* add static mappings */
352
		if (is_array($dhcpifconf['staticmap'])) {
353

    
354
			$i = 0;
355
			foreach ($dhcpifconf['staticmap'] as $sm) {
356
				$dhcpdconf .= <<<EOD
357
host s_{$dhcpif}_{$i} {
358
	hardware ethernet {$sm['mac']};
359

    
360
EOD;
361
				if ($sm['ipaddr'])
362
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
363

    
364
				if ($sm['hostname']) {
365
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
366
					$dhhostname = str_replace(".", "_", $dhhostname);
367
					$dhcpdconf .= "	option host-name \"{$dhhostname}\";\n";
368
				}
369
				if ($sm['netbootfile'])
370
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
371

    
372
				$dhcpdconf .= "}\n";
373
				$i++;
374
			}
375
		}
376

    
377
		$dhcpdifs[] = get_real_interface($dhcpif);
378
	}
379

    
380
	fwrite($fd, $dhcpdconf);
381
	fclose($fd);
382

    
383
	/* create an empty leases database */
384
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
385
	touch("{$g['varrun_path']}/dhcpd.pid");
386
	
387

    
388
	/* fire up dhcpd in a chroot */
389
	mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf " .
390
		join(" ", $dhcpdifs));
391

    
392
	if ($g['booting']) {
393
		print "done.\n";
394
	}
395

    
396
	return 0;
397
}
398

    
399
function services_igmpproxy_configure() {
400
        global $config, $g;
401

    
402
        /* kill any running igmpproxy */
403
        killbyname("igmpproxy");
404

    
405
	if (!is_array($config['igmpproxy']['igmpentry']))
406
		return 1;
407

    
408
        $iflist = get_configured_interface_list();
409

    
410
        $igmpconf = <<<EOD
411

    
412
##------------------------------------------------------
413
## Enable Quickleave mode (Sends Leave instantly)
414
##------------------------------------------------------
415
quickleave
416

    
417
EOD;
418

    
419
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
420
                unset($iflist[$igmpcf['ifname']]);
421
                $realif = get_real_interface($igmpcf['ifname']);
422
                if (empty($igmpcf['threshold']))
423
                        $threshld = 1;
424
                else
425
                        $threshld = $igmpcf['threshold'];
426
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
427

    
428
                if ($igmpcf['address'] <> "") {
429
                        $item = explode(" ", $igmpcf['address']);
430
                        foreach($item as $iww)
431
                                $igmpconf .= "altnet {$iww}\n";
432
                }
433
                $igmpconf .= "\n";
434
        }
435
        foreach ($iflist as $ifn) {
436
                $realif = get_real_interface($ifn);
437
                $igmpconf .= "phyint {$realif} disabled\n";
438
        }
439
	$igmpconf .= "\n";
440

    
441
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
442
        if (!$igmpfl) {
443
                log_error("Could not write Igmpproxy configuration file!");
444
                return;
445
        }
446
        fwrite($igmpfl, $igmpconf);
447
        fclose($igmpfl);
448

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

    
452
        return 0;
453
}
454

    
455
function services_dhcrelay_configure() {
456
	global $config, $g;
457
	if(isset($config['system']['developerspew'])) {
458
		$mt = microtime();
459
		echo "services_dhcrelay_configure() being called $mt\n";
460
	}
461

    
462
	/* kill any running dhcrelay */
463
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
464

    
465
	$dhcrelaycfg =& $config['dhcrelay'];
466

    
467
	/* DHCPRelay enabled on any interfaces? */
468
	if (!isset($dhcrelaycfg['enable']))
469
		return 0;
470

    
471
	if ($g['booting'])
472
		echo "Starting DHCP relay service...";
473
	else
474
		sleep(1);
475

    
476
	$iflist = get_configured_interface_list();
477

    
478
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
479
	foreach ($dhcifaces as $dhcrelayif) {
480
		if (!isset($iflist[$dhcrelayif]) ||
481
			link_interface_to_bridge($dhcrelayif))
482
			continue;
483

    
484
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
485
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
486
	}
487

    
488
	/* 
489
	 * In order for the relay to work, it needs to be active
490
	 * on the interface in which the destination server sits.
491
	 */
492
	$srvips = explode(",", $dhcrelaycfg['server']);
493
	foreach ($srvips as $srcidx => $srvip) {
494
		unset($destif);
495
		foreach ($iflist as $ifname) {
496
			$subnet = get_interface_ip($ifname);
497
			if (!is_ipaddr($subnet))
498
				continue;
499
			$subnet .=  "/" . get_interface_subnet($ifname);
500
			if (ip_in_subnet($srvip, $subnet)) {
501
				$destif = get_real_interface($ifname);
502
				break;
503
			}
504
		}
505
		if (!isset($destif)) {
506
			if (is_array($config['staticroutes']['route'])) {
507
				foreach ($config['staticroutes']['route'] as $rtent) {
508
					if (ip_in_subnet($srvip, $rtent['network'])) {
509
						$a_gateways = return_gateways_array(true);
510
						$destif = $a_gateways[$rtent['gateway']]['interface'];
511
						break;
512
					}
513
				}
514
			}
515
		}
516

    
517
		if (!isset($destif)) {
518
			/* Create a array from the existing route table */
519
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
520
        		array_shift($route_str);
521
        		array_shift($route_str);
522
        		array_shift($route_str);
523
        		array_shift($route_str);
524
        		$route_arr = array();
525
        		foreach($route_str as $routeline) {
526
                		$items = preg_split("/[ ]+/i", $routeline);
527
				if (ip_in_subnet($srvip, $items[0])) {
528
					$destif = trim($items[6]);
529
					break;
530
				}
531
        		}
532
		}
533
	
534
		if (!isset($destif)) {
535
			if (is_array($config['gateways']['gateway_item'])) {
536
				foreach ($config['gateways']['gateway_item'] as $gateway) {
537
					if (isset($gateway['defaultgw'])) {
538
						$a_gateways = return_gateways_array(true);
539
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
540
						break;
541
					}		
542
				}
543
			} else
544
				$destif = get_real_interface("wan");
545
		}
546

    
547
		if (!empty($destif))
548
			$dhcrelayifs[] = $destif;
549
	}
550
	$dhcrelayifs = array_unique($dhcrelayifs);
551

    
552
	/* fire up dhcrelay */
553
	if (empty($dhcrelayifs)) {
554
		log_error("No suitable interface found for running dhcrelay!");
555
		return; /* XXX */
556
	}
557

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

    
560
	if (isset($dhcrelaycfg['agentoption']))
561
		$cmd .=  " -a -m replace";
562

    
563
	$cmd .= " " . implode(" ", $srvips);
564
	mwexec($cmd);
565

    
566
	return 0;
567
}
568

    
569
function services_dyndns_configure_client($conf) {
570

    
571
	if (!isset($conf['enable']))
572
		return;
573

    
574
	/* load up the dyndns.class */
575
	require_once("dyndns.class");
576

    
577
	$dns = new updatedns($dnsService = $conf['type'],
578
		$dnsHost = $conf['host'],
579
		$dnsUser = $conf['username'],
580
		$dnsPass = $conf['password'],
581
		$dnsWilcard = $conf['wildcard'],
582
		$dnsMX = $conf['mx'], 
583
		$dnsIf = "{$conf['interface']}");
584
}
585

    
586
function services_dyndns_configure($int = "") {
587
	global $config, $g;
588
	if(isset($config['system']['developerspew'])) {
589
		$mt = microtime();
590
		echo "services_dyndns_configure() being called $mt\n";
591
	}
592

    
593
	$dyndnscfg = $config['dyndnses']['dyndns'];
594

    
595
	if (is_array($dyndnscfg)) {
596
		if ($g['booting']) 
597
			echo "Starting DynDNS clients...";
598

    
599
		foreach ($dyndnscfg as $dyndns) {
600
			if (!empty($int) && $int != $dyndns['interface'])
601
				continue;
602

    
603
			services_dyndns_configure_client($dyndns);
604

    
605
			sleep(1);
606
		}
607

    
608
		if ($g['booting'])
609
			echo "done.\n";
610
	}
611

    
612
	return 0;
613
}
614

    
615
function services_dnsmasq_configure() {
616
	global $config, $g;
617
	$return = 0;
618
	
619
	if(isset($config['system']['developerspew'])) {
620
		$mt = microtime();
621
		echo "services_dnsmasq_configure() being called $mt\n";
622
	}
623

    
624
	/* kill any running dnsmasq */
625
	if (file_exists("{$g['varrun_path']}/dnsmasq.pid"))
626
		sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
627

    
628
	if (isset($config['dnsmasq']['enable'])) {
629

    
630
		if ($g['booting'])
631
			echo "Starting DNS forwarder...";
632
		else
633
			sleep(1);
634

    
635
		/* generate hosts file */
636
		if(system_hosts_generate()!=0)
637
			$return = 1;
638

    
639
		$args = "";
640

    
641
		if (isset($config['dnsmasq']['regdhcp'])) {
642
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
643
		}
644
		
645
		/* Setup forwarded domains */
646
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
647
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
648
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
649
			}
650
		}
651

    
652
		/* Allow DNS Rebind for forwarded domains */
653
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
654
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
655
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
656
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
657
				}
658
			}
659
		}
660

    
661
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
662
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
663

    
664
		if ($config['dnsmasq']['custom_options']) {
665
			foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
666
				$args .= " --$c";
667
		}
668

    
669
		/* run dnsmasq */
670
		mwexec_bg("/usr/local/sbin/dnsmasq --local-ttl 1 --all-servers {$dns_rebind} --dns-forward-max=5000 --cache-size=10000 {$args}");
671

    
672
		if ($g['booting'])
673
			echo "done.\n";
674
	}
675

    
676
	if (!$g['booting']) {
677
		if(services_dhcpd_configure()!=0)
678
			$return = 1;
679
	}
680

    
681
	return $return;
682
}
683

    
684
function services_snmpd_configure() {
685
	global $config, $g;
686
	if(isset($config['system']['developerspew'])) {
687
		$mt = microtime();
688
		echo "services_snmpd_configure() being called $mt\n";
689
	}
690

    
691
	/* kill any running snmpd */
692
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
693
	sleep(2);
694
	if(is_process_running("bsnmpd")) 
695
		mwexec("/usr/bin/killall bsnmpd", true);
696

    
697
	if (isset($config['snmpd']['enable'])) {
698

    
699
		if ($g['booting'])
700
			echo "Starting SNMP daemon... ";
701

    
702
		/* generate snmpd.conf */
703
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
704
		if (!$fd) {
705
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
706
			return 1;
707
		}
708

    
709

    
710
		$snmpdconf = <<<EOD
711
location := "{$config['snmpd']['syslocation']}"
712
contact := "{$config['snmpd']['syscontact']}"
713
read := "{$config['snmpd']['rocommunity']}"
714

    
715
EOD;
716

    
717
/* No docs on what write strings do there for disable for now.
718
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
719
		    $snmpdconf .= <<<EOD
720
# write string
721
write := "{$config['snmpd']['rwcommunity']}"
722

    
723
EOD;
724
		}
725
*/
726

    
727

    
728
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
729
		    $snmpdconf .= <<<EOD
730
# SNMP Trap support.
731
traphost := {$config['snmpd']['trapserver']}
732
trapport := {$config['snmpd']['trapserverport']}
733
trap := "{$config['snmpd']['trapstring']}"
734

    
735

    
736
EOD;
737
		}
738

    
739

    
740
		$snmpdconf .= <<<EOD
741
system := 1     # pfSense
742
%snmpd
743
begemotSnmpdDebugDumpPdus       = 2
744
begemotSnmpdDebugSyslogPri      = 7
745
begemotSnmpdCommunityString.0.1 = $(read)
746

    
747
EOD;
748

    
749
/* No docs on what write strings do there for disable for now.
750
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
751
		    $snmpdconf .= <<<EOD
752
begemotSnmpdCommunityString.0.2 = $(write)
753

    
754
EOD;
755
		}
756
*/
757

    
758

    
759
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
760
		    $snmpdconf .= <<<EOD
761
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
762
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
763
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
764

    
765
EOD;
766
		}
767

    
768

    
769
		$snmpdconf .= <<<EOD
770
begemotSnmpdCommunityDisable    = 1
771

    
772
EOD;
773

    
774
		$bind_to_ip = "0.0.0.0";
775
		if(isset($config['snmpd']['bindip'])) {
776
			if (is_ipaddr($config['snmpd']['bindip'])) {
777
				$bind_to_ip = $config['snmpd']['bindip'];
778
			} else {
779
				$if = get_real_interface($config['snmpd']['bindip']);
780
				if (does_interface_exist($if))
781
					$bind_to_ip = find_interface_ip($if);
782
			}
783
		}
784

    
785
		if(is_port( $config['snmpd']['pollport'] )) {
786
		    $snmpdconf .= <<<EOD
787
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
788

    
789
EOD;
790

    
791
		}
792

    
793
		$snmpdconf .= <<<EOD
794
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
795
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
796

    
797
# These are bsnmp macros not php vars.
798
sysContact      = $(contact)
799
sysLocation     = $(location)
800
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
801

    
802
snmpEnableAuthenTraps = 2
803

    
804
EOD;
805

    
806
		if (is_array( $config['snmpd']['modules'] )) {
807
		    if(isset($config['snmpd']['modules']['mibii'])) {
808
			$snmpdconf .= <<<EOD
809
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
810

    
811
EOD;
812
		    }
813

    
814
		    if(isset($config['snmpd']['modules']['netgraph'])) {
815
			$snmpdconf .= <<<EOD
816
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
817
%netgraph
818
begemotNgControlNodeName = "snmpd"
819

    
820
EOD;
821
		    }
822

    
823
		    if(isset($config['snmpd']['modules']['pf'])) {
824
			$snmpdconf .= <<<EOD
825
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
826

    
827
EOD;
828
		    }
829

    
830
		    if(isset($config['snmpd']['modules']['hostres'])) {
831
			$snmpdconf .= <<<EOD
832
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
833

    
834
EOD;
835
		    }
836
		    if(isset($config['snmpd']['modules']['bridge'])) {
837
			$snmpdconf .= <<<EOD
838
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
839
# config must end with blank line
840

    
841

    
842
EOD;
843
		    }
844
		}
845

    
846
		fwrite($fd, $snmpdconf);
847
		fclose($fd);
848

    
849
		if (isset($config['snmpd']['bindlan'])) {
850
			$bindlan = "";
851
		}
852

    
853
		/* run bsnmpd */
854
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
855
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
856

    
857
		if ($g['booting'])
858
			echo "done.\n";
859
	}
860

    
861
	return 0;
862
}
863

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

    
871
	/* Dynamic DNS updating active? */
872
	if (is_array($config['dnsupdates']['dnsupdate'])) {
873
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
874
			if (!isset($dnsupdate['enable']))
875
				continue;
876
			if (!empty($int) && $int != $dnsupdate['interface'])
877
				continue;
878

    
879
			/* determine interface name */
880
			$if = get_real_interface($dnsupdate['interface']);
881
			$wanip = get_interface_ip($dnsupdate['interface']);
882
			if ($wanip) {
883

    
884
				$keyname = $dnsupdate['keyname'];
885
				/* trailing dot */
886
				if (substr($keyname, -1) != ".")
887
					$keyname .= ".";
888

    
889
				$hostname = $dnsupdate['host'];
890
				/* trailing dot */
891
				if (substr($hostname, -1) != ".")
892
					$hostname .= ".";
893

    
894
				/* write private key file
895
				   this is dumb - public and private keys are the same for HMAC-MD5,
896
				   but nsupdate insists on having both */
897
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
898
				$privkey = <<<EOD
899
Private-key-format: v1.2
900
Algorithm: 157 (HMAC)
901
Key: {$dnsupdate['keydata']}
902

    
903
EOD;
904
				fwrite($fd, $privkey);
905
				fclose($fd);
906

    
907
				/* write public key file */
908
				if ($dnsupdate['keytype'] == "zone") {
909
					$flags = 257;
910
					$proto = 3;
911
				} else if ($dnsupdate['keytype'] == "host") {
912
					$flags = 513;
913
					$proto = 3;
914
				} else if ($dnsupdate['keytype'] == "user") {
915
					$flags = 0;
916
					$proto = 2;
917
				}
918

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

    
923
				/* generate update instructions */
924
				$upinst = "";
925
				if (!empty($dnsupdate['server']))
926
					$upinst .= "server {$dnsupdate['server']}\n";
927
				$upinst .= "update delete {$dnsupdate['host']} A\n";
928
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
929
				$upinst .= "\n";	/* mind that trailing newline! */
930

    
931
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
932
				fwrite($fd, $upinst);
933
				fclose($fd);
934

    
935
				/* invoke nsupdate */
936
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
937
				if (isset($dnsupdate['usetcp']))
938
					$cmd .= " -v";
939
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
940
	
941
				mwexec_bg($cmd);
942
			}
943
		}
944
	}
945

    
946
	return 0;
947
}
948

    
949
function setup_wireless_olsr() {
950
	global $config, $g;
951
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
952
		return;
953
	if(isset($config['system']['developerspew'])) {
954
		$mt = microtime();
955
		echo "setup_wireless_olsr($interface) being called $mt\n";
956
	}
957
	conf_mount_rw();
958
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
959
		$olsr_enable = $olsrd['enable'];
960
		if($olsr_enable <> "on") {
961
			if (is_process_running("olsrd"))
962
				mwexec("/usr/bin/killall olsrd", true);
963
			return;
964
		}
965
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
966

    
967
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
968
			$enableannounce .= "\nHna4\n";
969
			$enableannounce .= "{\n";
970
		if($olsrd['announcedynamicroute'])
971
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
972
		if($olsrd['enableannounce'] == "on")
973
			$enableannounce .= "0.0.0.0 0.0.0.0";
974
			$enableannounce .= "\n}\n";
975
		} else {
976
			$enableannounce = "";
977
		}
978

    
979
		$olsr .= <<<EODA
980
#
981
# olsr.org OLSR daemon config file
982
#
983
# Lines starting with a # are discarded
984
#
985
# This file was generated by setup_wireless_olsr() in services.inc
986
#
987

    
988
# This file is an example of a typical
989
# configuration for a mostly static
990
# network(regarding mobility) using
991
# the LQ extention
992

    
993
# Debug level(0-9)
994
# If set to 0 the daemon runs in the background
995

    
996
DebugLevel	2
997

    
998
# IP version to use (4 or 6)
999

    
1000
IpVersion	4
1001

    
1002
# Clear the screen each time the internal state changes
1003

    
1004
ClearScreen     yes
1005

    
1006
{$enableannounce}
1007

    
1008
# Should olsrd keep on running even if there are
1009
# no interfaces available? This is a good idea
1010
# for a PCMCIA/USB hotswap environment.
1011
# "yes" OR "no"
1012

    
1013
AllowNoInt	yes
1014

    
1015
# TOS(type of service) value for
1016
# the IP header of control traffic.
1017
# If not set it will default to 16
1018

    
1019
#TosValue	16
1020

    
1021
# The fixed willingness to use(0-7)
1022
# If not set willingness will be calculated
1023
# dynamically based on battery/power status
1024
# if such information is available
1025

    
1026
#Willingness    	4
1027

    
1028
# Allow processes like the GUI front-end
1029
# to connect to the daemon.
1030

    
1031
IpcConnect
1032
{
1033
     # Determines how many simultaneously
1034
     # IPC connections that will be allowed
1035
     # Setting this to 0 disables IPC
1036

    
1037
     MaxConnections  0
1038

    
1039
     # By default only 127.0.0.1 is allowed
1040
     # to connect. Here allowed hosts can
1041
     # be added
1042

    
1043
     Host            127.0.0.1
1044
     #Host            10.0.0.5
1045

    
1046
     # You can also specify entire net-ranges
1047
     # that are allowed to connect. Multiple
1048
     # entries are allowed
1049

    
1050
     #Net             192.168.1.0 255.255.255.0
1051
}
1052

    
1053
# Wether to use hysteresis or not
1054
# Hysteresis adds more robustness to the
1055
# link sensing but delays neighbor registration.
1056
# Used by default. 'yes' or 'no'
1057

    
1058
UseHysteresis	no
1059

    
1060
# Hysteresis parameters
1061
# Do not alter these unless you know
1062
# what you are doing!
1063
# Set to auto by default. Allowed
1064
# values are floating point values
1065
# in the interval 0,1
1066
# THR_LOW must always be lower than
1067
# THR_HIGH.
1068

    
1069
#HystScaling	0.50
1070
#HystThrHigh	0.80
1071
#HystThrLow	0.30
1072

    
1073

    
1074
# Link quality level
1075
# 0 = do not use link quality
1076
# 1 = use link quality for MPR selection
1077
# 2 = use link quality for MPR selection and routing
1078
# Defaults to 0
1079

    
1080
LinkQualityLevel	{$olsrd['enablelqe']}
1081

    
1082
# Link quality window size
1083
# Defaults to 10
1084

    
1085
LinkQualityWinSize	10
1086

    
1087
# Polling rate in seconds(float).
1088
# Default value 0.05 sec
1089

    
1090
Pollrate	0.05
1091

    
1092

    
1093
# TC redundancy
1094
# Specifies how much neighbor info should
1095
# be sent in TC messages
1096
# Possible values are:
1097
# 0 - only send MPR selectors
1098
# 1 - send MPR selectors and MPRs
1099
# 2 - send all neighbors
1100
#
1101
# defaults to 0
1102

    
1103
TcRedundancy	2
1104

    
1105
#
1106
# MPR coverage
1107
# Specifies how many MPRs a node should
1108
# try select to reach every 2 hop neighbor
1109
#
1110
# Can be set to any integer >0
1111
#
1112
# defaults to 1
1113

    
1114
MprCoverage	3
1115

    
1116
# Example plugin entry with parameters:
1117

    
1118
EODA;
1119

    
1120
if($olsrd['enablehttpinfo'] == "on") {
1121
	$olsr .= <<<EODB
1122

    
1123
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1124
{
1125
    PlParam     "port"   "{$olsrd['port']}"
1126
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1127
}
1128

    
1129
EODB;
1130

    
1131
}
1132

    
1133
if($olsrd['enabledsecure'] == "on") {
1134
	$olsr .= <<<EODC
1135

    
1136
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1137
{
1138
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1139
}
1140

    
1141
EODC;
1142

    
1143
}
1144

    
1145
if($olsrd['enabledyngw'] == "on") {
1146

    
1147
	/* unset default route, olsr auto negotiates */
1148
	mwexec("/sbin/route delete default");
1149

    
1150
	$olsr .= <<<EODE
1151

    
1152
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1153
{
1154
    # how often to look for a inet gw, in seconds
1155
    # defaults to 5 secs, if commented out
1156
    PlParam     "Interval"   "{$olsrd['polling']}"
1157

    
1158
    # if one or more IPv4 addresses are given, do a ping on these in
1159
    # descending order to validate that there is not only an entry in
1160
    # routing table, but also a real internet connection. If any of
1161
    # these addresses could be pinged successfully, the test was
1162
    # succesful, i.e. if the ping on the 1st address was successful,the
1163
    # 2nd won't be pinged
1164
    PlParam     "Ping"       "{$olsrd['ping']}"
1165
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1166
}
1167

    
1168
EODE;
1169

    
1170
}
1171

    
1172
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1173
	$interfaces = explode(',', $conf['iface_array']);
1174
	foreach($interfaces as $interface) {
1175
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1176
$olsr .= <<<EODAD
1177
Interface "{$realinterface}"
1178
{
1179

    
1180
    # Hello interval in seconds(float)
1181
    HelloInterval    2.0
1182

    
1183
    # HELLO validity time
1184
    HelloValidityTime	20.0
1185

    
1186
    # TC interval in seconds(float)
1187
    TcInterval        5.0
1188

    
1189
    # TC validity time
1190
    TcValidityTime	30.0
1191

    
1192
    # MID interval in seconds(float)
1193
    MidInterval	5.0
1194

    
1195
    # MID validity time
1196
    MidValidityTime	30.0
1197

    
1198
    # HNA interval in seconds(float)
1199
    HnaInterval	5.0
1200

    
1201
    # HNA validity time
1202
    HnaValidityTime 	30.0
1203

    
1204
    # When multiple links exist between hosts
1205
    # the weight of interface is used to determine
1206
    # the link to use. Normally the weight is
1207
    # automatically calculated by olsrd based
1208
    # on the characteristics of the interface,
1209
    # but here you can specify a fixed value.
1210
    # Olsrd will choose links with the lowest value.
1211

    
1212
    # Weight 0
1213

    
1214

    
1215
}
1216

    
1217
EODAD;
1218

    
1219
	}
1220
	break;
1221
}
1222
		fwrite($fd, $olsr);
1223
		fclose($fd);
1224
	}
1225

    
1226
	if (is_process_running("olsrd"))
1227
		mwexec("/usr/bin/killall olsrd", true);
1228

    
1229
	sleep(2);
1230

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

    
1233
	conf_mount_ro();
1234
}
1235

    
1236
/* configure cron service */
1237
function configure_cron() {
1238
	global $g, $config;
1239

    
1240
	conf_mount_rw();
1241
	/* preserve existing crontab entries */
1242
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1243
	
1244
	for ($i = 0; $i < count($crontab_contents); $i++) {
1245
		$cron_item =& $crontab_contents[$i];
1246
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
1247
			array_splice($crontab_contents, $i - 1);
1248
			break;
1249
		}
1250
	}
1251
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
1252
	
1253
	
1254
	if (is_array($config['cron']['item'])) {
1255
		$crontab_contents .= "#\n";
1256
		$crontab_contents .= "# pfSense specific crontab entries\n";
1257
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1258
		$crontab_contents .= "#\n";
1259

    
1260
		foreach ($config['cron']['item'] as $item) {
1261
			$crontab_contents .= "\n{$item['minute']}\t";
1262
			$crontab_contents .= "{$item['hour']}\t";
1263
			$crontab_contents .= "{$item['mday']}\t";
1264
			$crontab_contents .= "{$item['month']}\t";
1265
			$crontab_contents .= "{$item['wday']}\t";
1266
			$crontab_contents .= "{$item['who']}\t";
1267
			$crontab_contents .= "{$item['command']}";
1268
		}
1269
    
1270
		$crontab_contents .= "\n#\n";
1271
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1272
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1273
		$crontab_contents .= "#\n\n";
1274
	}
1275
	
1276
	/* please maintain the newline at the end of file */
1277
	file_put_contents("/etc/crontab", $crontab_contents);
1278

    
1279
	/* do a HUP kill to force sync changes */
1280
	exec('/bin/pkill -HUP cron');
1281

    
1282
	conf_mount_ro();
1283
}
1284

    
1285
function upnp_action ($action) {
1286
	global $g, $config;
1287
	switch($action) {
1288
		case "start":
1289
			if (file_exists('/var/etc/miniupnpd.conf')) {
1290
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
1291
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
1292
			}
1293
			break;
1294
		case "stop":
1295
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
1296
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
1297
				mwexec('killall miniupnpd 2>/dev/null', true);
1298
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1299
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1300
			break;
1301
		case "restart":
1302
			upnp_action('stop');
1303
			upnp_action('start');
1304
			break;
1305
	}
1306
}
1307

    
1308
function upnp_start() {
1309
	global $config;
1310

    
1311
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1312
		return;
1313

    
1314
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1315
		echo "Starting UPnP service... ";
1316
		require_once('/usr/local/pkg/miniupnpd.inc');
1317
		sync_package_miniupnpd();
1318
		echo "done.\n";
1319
	}
1320
}
1321

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

    
1325
	$is_installed = false;
1326

    
1327
	if(!$config['cron']['item'])
1328
		return;
1329

    
1330
	$x=0;
1331
	foreach($config['cron']['item'] as $item) {
1332
		if(strstr($item['command'], $command)) {
1333
			$is_installed = true;
1334
			break;
1335
		}
1336
		$x++;
1337
	}
1338

    
1339
	if($active) {
1340
		$cron_item = array();
1341
		$cron_item['minute'] = $minute;
1342
		$cron_item['hour'] = $hour;
1343
		$cron_item['mday'] = $monthday;
1344
		$cron_item['month'] = $month;
1345
		$cron_item['wday'] = $weekday;
1346
		$cron_item['who'] = $who;
1347
		$cron_item['command'] = $command;
1348
		if(!$is_installed) {
1349
			$config['cron']['item'][] = $cron_item;
1350
			write_config("Installed cron job for {$command}");
1351
		} else {
1352
			$config['cron']['item'][$x] = $cron_item;
1353
			write_config("Updated cron job for {$command}");
1354
		}
1355
	} else {
1356
		if(($is_installed == true) && ($x > 0)) {
1357
			unset($config['cron']['item'][$x]);
1358
			write_config("Remvoed cron job for {$command}");
1359
		}
1360
	}
1361
	configure_cron();
1362
}
1363

    
1364
?>
(45-45/62)