Project

General

Profile

Download (35.7 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
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
626

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

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

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

    
638
		$args = "";
639

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

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

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

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

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

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

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

    
680
	return $return;
681
}
682

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

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

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

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

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

    
708

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

    
714
EOD;
715

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

    
722
EOD;
723
		}
724
*/
725

    
726

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

    
734

    
735
EOD;
736
		}
737

    
738

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

    
746
EOD;
747

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

    
753
EOD;
754
		}
755
*/
756

    
757

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

    
764
EOD;
765
		}
766

    
767

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

    
771
EOD;
772

    
773
		if(isset($config['snmpd']['bindlan'])) {
774
			$bind_to_ip = get_interface_ip("lan");
775
		} else {
776
			$bind_to_ip = "0.0.0.0";
777
		}
778

    
779
		if(is_port( $config['snmpd']['pollport'] )) {
780
		    $snmpdconf .= <<<EOD
781
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
782

    
783
EOD;
784

    
785
		}
786

    
787
		$snmpdconf .= <<<EOD
788
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
789
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
790

    
791
# These are bsnmp macros not php vars.
792
sysContact      = $(contact)
793
sysLocation     = $(location)
794
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
795

    
796
snmpEnableAuthenTraps = 2
797

    
798
EOD;
799

    
800
		if (is_array( $config['snmpd']['modules'] )) {
801
		    if(isset($config['snmpd']['modules']['mibii'])) {
802
			$snmpdconf .= <<<EOD
803
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
804

    
805
EOD;
806
		    }
807

    
808
		    if(isset($config['snmpd']['modules']['netgraph'])) {
809
			$snmpdconf .= <<<EOD
810
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
811
%netgraph
812
begemotNgControlNodeName = "snmpd"
813

    
814
EOD;
815
		    }
816

    
817
		    if(isset($config['snmpd']['modules']['pf'])) {
818
			$snmpdconf .= <<<EOD
819
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
820

    
821
EOD;
822
		    }
823

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

    
828
EOD;
829
		    }
830
		    if(isset($config['snmpd']['modules']['bridge'])) {
831
			$snmpdconf .= <<<EOD
832
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
833
# config must end with blank line
834

    
835

    
836
EOD;
837
		    }
838
		}
839

    
840
		fwrite($fd, $snmpdconf);
841
		fclose($fd);
842

    
843
		if (isset($config['snmpd']['bindlan'])) {
844
			$bindlan = "";
845
		}
846

    
847
		/* run bsnmpd */
848
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
849
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
850

    
851
		if ($g['booting'])
852
			echo "done.\n";
853
	}
854

    
855
	return 0;
856
}
857

    
858
function services_dnsupdate_process($int = "") {
859
	global $config, $g;
860
	if(isset($config['system']['developerspew'])) {
861
		$mt = microtime();
862
		echo "services_dnsupdate_process() being called $mt\n";
863
	}
864

    
865
	/* Dynamic DNS updating active? */
866
	if (is_array($config['dnsupdates']['dnsupdate'])) {
867
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
868
			if (!isset($dnsupdate['enable']))
869
				continue;
870
			if (!empty($int) && $int != $dnsupdate['interface'])
871
				continue;
872

    
873
			/* determine interface name */
874
			$if = get_real_interface($dnsupdate['interface']);
875
			$wanip = get_interface_ip($dnsupdate['interface']);
876
			if ($wanip) {
877

    
878
				$keyname = $dnsupdate['keyname'];
879
				/* trailing dot */
880
				if (substr($keyname, -1) != ".")
881
					$keyname .= ".";
882

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

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

    
897
EOD;
898
				fwrite($fd, $privkey);
899
				fclose($fd);
900

    
901
				/* write public key file */
902
				if ($dnsupdate['keytype'] == "zone") {
903
					$flags = 257;
904
					$proto = 3;
905
				} else if ($dnsupdate['keytype'] == "host") {
906
					$flags = 513;
907
					$proto = 3;
908
				} else if ($dnsupdate['keytype'] == "user") {
909
					$flags = 0;
910
					$proto = 2;
911
				}
912

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

    
917
				/* generate update instructions */
918
				$upinst = "";
919
				if (!empty($dnsupdate['server']))
920
					$upinst .= "server {$dnsupdate['server']}\n";
921
				$upinst .= "update delete {$dnsupdate['host']} A\n";
922
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
923
				$upinst .= "\n";	/* mind that trailing newline! */
924

    
925
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
926
				fwrite($fd, $upinst);
927
				fclose($fd);
928

    
929
				/* invoke nsupdate */
930
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
931
				if (isset($dnsupdate['usetcp']))
932
					$cmd .= " -v";
933
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
934
	
935
				mwexec_bg($cmd);
936
			}
937
		}
938
	}
939

    
940
	return 0;
941
}
942

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

    
961
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
962
			$enableannounce .= "\nHna4\n";
963
			$enableannounce .= "{\n";
964
		if($olsrd['announcedynamicroute'])
965
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
966
		if($olsrd['enableannounce'] == "on")
967
			$enableannounce .= "0.0.0.0 0.0.0.0";
968
			$enableannounce .= "\n}\n";
969
		} else {
970
			$enableannounce = "";
971
		}
972

    
973
		$olsr .= <<<EODA
974
#
975
# olsr.org OLSR daemon config file
976
#
977
# Lines starting with a # are discarded
978
#
979
# This file was generated by setup_wireless_olsr() in services.inc
980
#
981

    
982
# This file is an example of a typical
983
# configuration for a mostly static
984
# network(regarding mobility) using
985
# the LQ extention
986

    
987
# Debug level(0-9)
988
# If set to 0 the daemon runs in the background
989

    
990
DebugLevel	2
991

    
992
# IP version to use (4 or 6)
993

    
994
IpVersion	4
995

    
996
# Clear the screen each time the internal state changes
997

    
998
ClearScreen     yes
999

    
1000
{$enableannounce}
1001

    
1002
# Should olsrd keep on running even if there are
1003
# no interfaces available? This is a good idea
1004
# for a PCMCIA/USB hotswap environment.
1005
# "yes" OR "no"
1006

    
1007
AllowNoInt	yes
1008

    
1009
# TOS(type of service) value for
1010
# the IP header of control traffic.
1011
# If not set it will default to 16
1012

    
1013
#TosValue	16
1014

    
1015
# The fixed willingness to use(0-7)
1016
# If not set willingness will be calculated
1017
# dynamically based on battery/power status
1018
# if such information is available
1019

    
1020
#Willingness    	4
1021

    
1022
# Allow processes like the GUI front-end
1023
# to connect to the daemon.
1024

    
1025
IpcConnect
1026
{
1027
     # Determines how many simultaneously
1028
     # IPC connections that will be allowed
1029
     # Setting this to 0 disables IPC
1030

    
1031
     MaxConnections  0
1032

    
1033
     # By default only 127.0.0.1 is allowed
1034
     # to connect. Here allowed hosts can
1035
     # be added
1036

    
1037
     Host            127.0.0.1
1038
     #Host            10.0.0.5
1039

    
1040
     # You can also specify entire net-ranges
1041
     # that are allowed to connect. Multiple
1042
     # entries are allowed
1043

    
1044
     #Net             192.168.1.0 255.255.255.0
1045
}
1046

    
1047
# Wether to use hysteresis or not
1048
# Hysteresis adds more robustness to the
1049
# link sensing but delays neighbor registration.
1050
# Used by default. 'yes' or 'no'
1051

    
1052
UseHysteresis	no
1053

    
1054
# Hysteresis parameters
1055
# Do not alter these unless you know
1056
# what you are doing!
1057
# Set to auto by default. Allowed
1058
# values are floating point values
1059
# in the interval 0,1
1060
# THR_LOW must always be lower than
1061
# THR_HIGH.
1062

    
1063
#HystScaling	0.50
1064
#HystThrHigh	0.80
1065
#HystThrLow	0.30
1066

    
1067

    
1068
# Link quality level
1069
# 0 = do not use link quality
1070
# 1 = use link quality for MPR selection
1071
# 2 = use link quality for MPR selection and routing
1072
# Defaults to 0
1073

    
1074
LinkQualityLevel	{$olsrd['enablelqe']}
1075

    
1076
# Link quality window size
1077
# Defaults to 10
1078

    
1079
LinkQualityWinSize	10
1080

    
1081
# Polling rate in seconds(float).
1082
# Default value 0.05 sec
1083

    
1084
Pollrate	0.05
1085

    
1086

    
1087
# TC redundancy
1088
# Specifies how much neighbor info should
1089
# be sent in TC messages
1090
# Possible values are:
1091
# 0 - only send MPR selectors
1092
# 1 - send MPR selectors and MPRs
1093
# 2 - send all neighbors
1094
#
1095
# defaults to 0
1096

    
1097
TcRedundancy	2
1098

    
1099
#
1100
# MPR coverage
1101
# Specifies how many MPRs a node should
1102
# try select to reach every 2 hop neighbor
1103
#
1104
# Can be set to any integer >0
1105
#
1106
# defaults to 1
1107

    
1108
MprCoverage	3
1109

    
1110
# Example plugin entry with parameters:
1111

    
1112
EODA;
1113

    
1114
if($olsrd['enablehttpinfo'] == "on") {
1115
	$olsr .= <<<EODB
1116

    
1117
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1118
{
1119
    PlParam     "port"   "{$olsrd['port']}"
1120
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1121
}
1122

    
1123
EODB;
1124

    
1125
}
1126

    
1127
if($olsrd['enabledsecure'] == "on") {
1128
	$olsr .= <<<EODC
1129

    
1130
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1131
{
1132
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1133
}
1134

    
1135
EODC;
1136

    
1137
}
1138

    
1139
if($olsrd['enabledyngw'] == "on") {
1140

    
1141
	/* unset default route, olsr auto negotiates */
1142
	mwexec("/sbin/route delete default");
1143

    
1144
	$olsr .= <<<EODE
1145

    
1146
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1147
{
1148
    # how often to look for a inet gw, in seconds
1149
    # defaults to 5 secs, if commented out
1150
    PlParam     "Interval"   "{$olsrd['polling']}"
1151

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

    
1162
EODE;
1163

    
1164
}
1165

    
1166
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1167
	$interfaces = explode(',', $conf['iface_array']);
1168
	foreach($interfaces as $interface) {
1169
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1170
$olsr .= <<<EODAD
1171
Interface "{$realinterface}"
1172
{
1173

    
1174
    # Hello interval in seconds(float)
1175
    HelloInterval    2.0
1176

    
1177
    # HELLO validity time
1178
    HelloValidityTime	20.0
1179

    
1180
    # TC interval in seconds(float)
1181
    TcInterval        5.0
1182

    
1183
    # TC validity time
1184
    TcValidityTime	30.0
1185

    
1186
    # MID interval in seconds(float)
1187
    MidInterval	5.0
1188

    
1189
    # MID validity time
1190
    MidValidityTime	30.0
1191

    
1192
    # HNA interval in seconds(float)
1193
    HnaInterval	5.0
1194

    
1195
    # HNA validity time
1196
    HnaValidityTime 	30.0
1197

    
1198
    # When multiple links exist between hosts
1199
    # the weight of interface is used to determine
1200
    # the link to use. Normally the weight is
1201
    # automatically calculated by olsrd based
1202
    # on the characteristics of the interface,
1203
    # but here you can specify a fixed value.
1204
    # Olsrd will choose links with the lowest value.
1205

    
1206
    # Weight 0
1207

    
1208

    
1209
}
1210

    
1211
EODAD;
1212

    
1213
	}
1214
	break;
1215
}
1216
		fwrite($fd, $olsr);
1217
		fclose($fd);
1218
	}
1219

    
1220
	if (is_process_running("olsrd"))
1221
		mwexec("/usr/bin/killall olsrd", true);
1222

    
1223
	sleep(2);
1224

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

    
1227
	conf_mount_ro();
1228
}
1229

    
1230
/* configure cron service */
1231
function configure_cron() {
1232
	global $g, $config;
1233

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

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

    
1273
	/* do a HUP kill to force sync changes */
1274
	exec('/bin/pkill -HUP cron');
1275

    
1276
	conf_mount_ro();
1277
}
1278

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

    
1302
function upnp_start() {
1303
	global $config;
1304

    
1305
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1306
		return;
1307

    
1308
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1309
		echo "Starting UPnP service... ";
1310
		require_once('/usr/local/pkg/miniupnpd.inc');
1311
		sync_package_miniupnpd();
1312
		echo "done.\n";
1313
	}
1314
}
1315

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

    
1319
	$is_installed = false;
1320

    
1321
	if(!$config['cron']['item'])
1322
		return;
1323

    
1324
	$x=0;
1325
	foreach($config['cron']['item'] as $item) {
1326
		if(strstr($item['command'], $command)) {
1327
			$is_installed = true;
1328
			break;
1329
		}
1330
		$x++;
1331
	}
1332

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

    
1358
?>
(44-44/61)