Project

General

Profile

Download (36.2 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/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
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = text;\n";
124
			}
125
		}
126
	}
127

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

    
142
EOD;
143

    
144
	if(!isset($dhcpifconf['disableauthoritative']))
145
		$dhcpdconf .= "authoritative;\n";
146

    
147
	if(isset($dhcpifconf['alwaysbroadcast'])) 
148
		$dhcpdconf .= "always-broadcast on\n";
149

    
150
	$dhcpdifs = array();
151

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

    
158
		interfaces_staticarp_configure($dhcpif);
159

    
160
		if (!isset($dhcpifconf['enable']))
161
			continue;
162

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

    
209
EOPP;
210
		$dhcpnum++;
211
		}
212
	}
213

    
214
	$dhcpnum = 0;
215

    
216
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
217

    
218
		$ifcfg = $config['interfaces'][$dhcpif];
219

    
220
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
221
			continue;
222
		$ifcfgip = get_interface_ip($dhcpif);
223
		$ifcfgsn = get_interface_subnet($dhcpif);
224
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
225
		$subnetmask = gen_subnet_mask($ifcfgsn);
226

    
227
		if($is_olsr_enabled == true)
228
			if($dhcpifconf['netmask'])
229
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
230

    
231
		$dnscfg = "";
232

    
233
		if ($dhcpifconf['domain']) {
234
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
235
		}
236
		
237
    		if($dhcpifconf['domainsearchlist'] <> "") {
238
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
239
    		}
240

    
241
		if (isset($dhcpifconf['ddnsupdate'])) {
242
			if($dhcpifconf['ddnsdomain'] <> "") {
243
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
244
			}
245
			$dnscfg .= "	ddns-update-style interim;\n";
246
		}
247

    
248
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
249
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
250
		} else if (isset($config['dnsmasq']['enable'])) {
251
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
252
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
253
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
254
		}
255

    
256
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
257
		$dhcpdconf .= "	pool {\n";
258

    
259
		/* is failover dns setup? */
260
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
261
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
262
			if($dhcpifconf['dnsserver'][1] <> "")
263
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
264
			$dhcpdconf .= ";\n";
265
		}
266

    
267
		if($dhcpifconf['failover_peerip'] <> "")
268
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
269

    
270
		if (isset($dhcpifconf['denyunknown']))
271
		   $dhcpdconf .= "		deny unknown clients;\n";
272

    
273
		if ($dhcpifconf['gateway'])
274
			$routers = $dhcpifconf['gateway'];
275
		else
276
			$routers = $ifcfgip;
277

    
278
		if($dhcpifconf['failover_peerip'] <> "") {
279
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
280
			$dhcpnum++;
281
		}
282

    
283
		$dhcpdconf .= <<<EOD
284
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
285
	}
286
	option routers {$routers};
287
$dnscfg
288

    
289
EOD;
290
    
291
		// default-lease-time
292
		if ($dhcpifconf['defaultleasetime'])
293
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
294

    
295
		// max-lease-time
296
		if ($dhcpifconf['maxleasetime'])
297
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
298

    
299
		// netbios-name*
300
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
301
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
302
			$dhcpdconf .= "	option netbios-node-type 8;\n";
303
		}
304

    
305
		// ntp-servers
306
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
307
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
308

    
309
		// tftp-server-name
310
		if ($dhcpifconf['tftp'] <> "")
311
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
312

    
313
		// Handle option, number rowhelper values
314
		$dhcpdconf .= "\n";
315
		if($dhcpifconf['numberoptions']['item']) {
316
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
317
				$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
318
			}
319
		}
320

    
321
		// ldap-server
322
		if ($dhcpifconf['ldap'] <> "")
323
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
324

    
325
		// net boot information
326
		if(isset($dhcpifconf['netboot'])) {
327
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
328
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
329
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
330
			}
331
			if ($dhcpifconf['rootpath'] <> "") {
332
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
333
      		}
334
		}
335
		
336
		$dhcpdconf .= <<<EOD
337
}
338

    
339
EOD;
340

    
341
		/* add static mappings */
342
		if (is_array($dhcpifconf['staticmap'])) {
343

    
344
			$i = 0;
345
			foreach ($dhcpifconf['staticmap'] as $sm) {
346
				$dhcpdconf .= <<<EOD
347
host s_{$dhcpif}_{$i} {
348
	hardware ethernet {$sm['mac']};
349

    
350
EOD;
351
				if ($sm['ipaddr'])
352
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
353

    
354
				if ($sm['hostname']) {
355
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
356
					$dhhostname = str_replace(".", "_", $dhhostname);
357
					$dhcpdconf .= "	option host-name {$dhhostname};\n";
358
				}
359
				if ($sm['netbootfile'])
360
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
361

    
362
				$dhcpdconf .= "}\n";
363
				$i++;
364
			}
365
		}
366

    
367
		$dhcpdifs[] = get_real_interface($dhcpif);
368
	}
369

    
370
	fwrite($fd, $dhcpdconf);
371
	fclose($fd);
372

    
373
	/* create an empty leases database */
374
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
375
	touch("{$g['varrun_path']}/dhcpd.pid");
376
	
377

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

    
382
	if ($g['booting']) {
383
		print "done.\n";
384
	}
385

    
386
	return 0;
387
}
388

    
389
function services_igmpproxy_configure() {
390
        global $config, $g;
391

    
392
        $iflist = get_configured_interface_list();
393

    
394
        /* kill any running igmpproxy */
395
        killbyname("igmpproxy");
396

    
397
	if (!is_array($config['igmpproxy']['igmpentry']))
398
		return 1;
399

    
400
        $igmpconf = <<<EOD
401

    
402
##------------------------------------------------------
403
## Enable Quickleave mode (Sends Leave instantly)
404
##------------------------------------------------------
405
quickleave
406

    
407
EOD;
408

    
409
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
410
                unset($iflist[$igmpcf['ifname']]);
411
                $realif = get_real_interface($igmpcf['ifname']);
412
                if (empty($igmpcf['threshold']))
413
                        $threshld = 1;
414
                else
415
                        $threshld = $igmpcf['threshold'];
416
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
417

    
418
                if ($igmpcf['address'] <> "") {
419
                        $item = explode(" ", $igmpcf['address']);
420
                        foreach($item as $iww)
421
                                $igmpconf .= "altnet {$iww}\n";
422
                }
423
                $igmpconf .= "\n";
424
        }
425
        foreach ($iflist as $ifn) {
426
                $realif = get_real_interface($ifn);
427
                $igmpconf .= "phyint {$realif} disabled\n";
428
        }
429

    
430
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
431
        if (!$igmpfl) {
432
                log_error("Could not write Igmpproxy configuration file!");
433
                return;
434
        }
435
        fwrite($igmpfl, $igmpconf);
436
        fclose($igmpfl);
437

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

    
441
        return 0;
442
}
443

    
444
function interfaces_staticarp_configure($if) {
445
	global $config, $g;
446
	if(isset($config['system']['developerspew'])) {
447
		$mt = microtime();
448
		echo "interfaces_staticarp_configure($if) being called $mt\n";
449
	}
450

    
451
        $ifcfg = $config['interfaces'][$if];
452

    
453
	if (empty($if) || empty($ifcfg['if']))
454
		return 0;
455

    
456
        /* Enable staticarp, if enabled */
457
        if(isset($config['dhcpd'][$if]['staticarp'])) {
458
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
459
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
460
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
461

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

    
465
                        }
466

    
467
                }
468
        } else {
469
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
470
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
471
        }
472

    
473
        return 0;
474
}
475

    
476
function services_dhcrelay_configure() {
477
	global $config, $g;
478
	if(isset($config['system']['developerspew'])) {
479
		$mt = microtime();
480
		echo "services_dhcrelay_configure() being called $mt\n";
481
	}
482

    
483
	/* kill any running dhcrelay */
484
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
485

    
486
	$dhcrelaycfg =& $config['dhcrelay'];
487

    
488
	/* DHCPRelay enabled on any interfaces? */
489
	if (!isset($dhcrelaycfg['enable']))
490
		return 0;
491

    
492
	if ($g['booting'])
493
		echo "Starting DHCP relay service...";
494
	else
495
		sleep(1);
496

    
497
	$iflist = get_configured_interface_list();
498

    
499
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
500
	foreach ($dhcifaces as $dhcrelayif) {
501
		if (!isset($iflist[$dhcrelayif]) ||
502
			link_interface_to_bridge($dhcrelayif))
503
			continue;
504

    
505
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
506
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
507
	}
508

    
509
	/* 
510
	 * In order for the relay to work, it needs to be active
511
	 * on the interface in which the destination server sits.
512
	 */
513
	$srvips = explode(",", $dhcrelaycfg['server']);
514
	foreach ($srvips as $srcidx => $srvip) {
515
		unset($destif);
516
		foreach ($iflist as $ifname) {
517
			$subnet = get_interface_ip($ifname);
518
			if (!is_ipaddr($subnet))
519
				continue;
520
			$subnet .=  "/" . get_interface_subnet($ifname);
521
			if (ip_in_subnet($srvip, $subnet)) {
522
				$destif = get_real_interface($ifname);
523
				break;
524
			}
525
		}
526
		if (!isset($destif)) {
527
			if (is_array($config['staticroutes']['route'])) {
528
				foreach ($config['staticroutes']['route'] as $rtent) {
529
					if (ip_in_subnet($srvip, $rtent['network'])) {
530
						$a_gateways = return_gateways_array(true);
531
						$destif = $a_gateways[$rtent['gateway']]['interface'];
532
						break;
533
					}
534
				}
535
			}
536
		}
537

    
538
		if (!isset($destif)) {
539
			/* Create a array from the existing route table */
540
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
541
        		array_shift($route_str);
542
        		array_shift($route_str);
543
        		array_shift($route_str);
544
        		array_shift($route_str);
545
        		$route_arr = array();
546
        		foreach($route_str as $routeline) {
547
                		$items = preg_split("/[ ]+/i", $routeline);
548
				if (ip_in_subnet($srvip, $items[0])) {
549
					$destif = trim($items[2]);
550
					break;
551
				}
552
        		}
553
		}
554
	
555
		if (!isset($destif)) {
556
			if (is_array($config['gateways']['gateway_item'])) {
557
				foreach ($config['gateways']['gateway_item'] as $gateway) {
558
					if (isset($gateway['defaultgw'])) {
559
						$a_gateways = return_gateways_array(true);
560
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
561
						break;
562
					}		
563
				}
564
			} else
565
				$destif = get_real_interface("wan");
566
		}
567

    
568
		if (!empty($destif))
569
			$dhcrelayifs[] = $destif;
570
	}
571
	$dhcrelayifs = array_unique($dhcrelayifs);
572

    
573
	/* fire up dhcrelay */
574
	if (empty($dhcrelayifs)) {
575
		log_error("No suitable interface found for running dhcrelay!");
576
		return; /* XXX */
577
	}
578

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

    
581
	if (isset($dhcrelaycfg['agentoption']))
582
		$cmd .=  " -a -m replace";
583

    
584
	$cmd .= " " . implode(" ", $srvips);
585
	mwexec($cmd);
586

    
587
	return 0;
588
}
589

    
590
function services_dyndns_configure_client($conf) {
591

    
592
	if (!isset($conf['enable']))
593
		return;
594

    
595
	/* load up the dyndns.class */
596
	require_once("dyndns.class");
597

    
598
	log_error("DynDns: Running updatedns()");
599

    
600
	$dns = new updatedns($dnsService = $conf['type'],
601
		$dnsHost = $conf['host'],
602
		$dnsUser = $conf['username'],
603
		$dnsPass = $conf['password'],
604
		$dnsWilcard = $conf['wildcard'],
605
		$dnsMX = $conf['mx'], 
606
		$dnsIf = "{$conf['interface']}");
607
}
608

    
609
function services_dyndns_configure($int = "") {
610
	global $config, $g;
611
	if(isset($config['system']['developerspew'])) {
612
		$mt = microtime();
613
		echo "services_dyndns_configure() being called $mt\n";
614
	}
615

    
616
	$dyndnscfg = $config['dyndnses']['dyndns'];
617

    
618
	if (is_array($dyndnscfg)) {
619
		if ($g['booting']) 
620
			echo "Starting DynDNS clients...";
621

    
622
		foreach ($dyndnscfg as $dyndns) {
623
			if (!empty($int) && $int != $dyndns['interface'])
624
				continue;
625

    
626
			services_dyndns_configure_client($dyndns);
627

    
628
			sleep(1);
629
		}
630

    
631
		if ($g['booting'])
632
			echo "done.\n";
633
	}
634

    
635
	return 0;
636
}
637

    
638
function services_dnsmasq_configure() {
639
	global $config, $g;
640
	$return = 0;
641
	
642
	if(isset($config['system']['developerspew'])) {
643
		$mt = microtime();
644
		echo "services_dnsmasq_configure() being called $mt\n";
645
	}
646

    
647
	/* kill any running dnsmasq */
648
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
649

    
650
	if (isset($config['dnsmasq']['enable'])) {
651

    
652
		if ($g['booting'])
653
			echo "Starting DNS forwarder...";
654
		else
655
			sleep(1);
656

    
657
		/* generate hosts file */
658
		if(system_hosts_generate()!=0)
659
			$return = 1;
660

    
661
		$args = "";
662

    
663
		if (isset($config['dnsmasq']['regdhcp'])) {
664
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
665
		}
666
		
667
		/* Setup forwarded domains */
668
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
669
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
670
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
671
			}
672
		}
673

    
674
		/* Allow DNS Rebind for forwarded domains */
675
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
676
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
677
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
678
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
679
				}
680
			}
681
		}
682

    
683
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
684
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
685

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

    
689
		if ($g['booting'])
690
			echo "done.\n";
691
	}
692

    
693
	if (!$g['booting']) {
694
		if(services_dhcpd_configure()!=0)
695
			$return = 1;
696
	}
697

    
698
	return $return;
699
}
700

    
701
function services_snmpd_configure() {
702
	global $config, $g;
703
	if(isset($config['system']['developerspew'])) {
704
		$mt = microtime();
705
		echo "services_snmpd_configure() being called $mt\n";
706
	}
707

    
708
	/* kill any running snmpd */
709
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
710
	if(is_process_running("bsnmpd")) 
711
		mwexec("/usr/bin/killall bsnmpd", true);
712

    
713
	if (isset($config['snmpd']['enable'])) {
714

    
715
		if ($g['booting'])
716
			echo "Starting SNMP daemon... ";
717

    
718
		/* generate snmpd.conf */
719
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
720
		if (!$fd) {
721
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
722
			return 1;
723
		}
724

    
725

    
726
		$snmpdconf = <<<EOD
727
location := "{$config['snmpd']['syslocation']}"
728
contact := "{$config['snmpd']['syscontact']}"
729
read := "{$config['snmpd']['rocommunity']}"
730

    
731
EOD;
732

    
733
/* No docs on what write strings do there for disable for now.
734
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
735
		    $snmpdconf .= <<<EOD
736
# write string
737
write := "{$config['snmpd']['rwcommunity']}"
738

    
739
EOD;
740
		}
741
*/
742

    
743

    
744
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
745
		    $snmpdconf .= <<<EOD
746
# SNMP Trap support.
747
traphost := {$config['snmpd']['trapserver']}
748
trapport := {$config['snmpd']['trapserverport']}
749
trap := "{$config['snmpd']['trapstring']}"
750

    
751

    
752
EOD;
753
		}
754

    
755

    
756
		$snmpdconf .= <<<EOD
757
system := 1     # pfSense
758
%snmpd
759
begemotSnmpdDebugDumpPdus       = 2
760
begemotSnmpdDebugSyslogPri      = 7
761
begemotSnmpdCommunityString.0.1 = $(read)
762

    
763
EOD;
764

    
765
/* No docs on what write strings do there for disable for now.
766
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
767
		    $snmpdconf .= <<<EOD
768
begemotSnmpdCommunityString.0.2 = $(write)
769

    
770
EOD;
771
		}
772
*/
773

    
774

    
775
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
776
		    $snmpdconf .= <<<EOD
777
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
778
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
779
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
780

    
781
EOD;
782
		}
783

    
784

    
785
		$snmpdconf .= <<<EOD
786
begemotSnmpdCommunityDisable    = 1
787

    
788
EOD;
789

    
790
		if(isset($config['snmpd']['bindlan'])) {
791
			$bind_to_ip = get_interface_ip("lan");
792
		} else {
793
			$bind_to_ip = "0.0.0.0";
794
		}
795

    
796
		if(is_port( $config['snmpd']['pollport'] )) {
797
		    $snmpdconf .= <<<EOD
798
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
799

    
800
EOD;
801

    
802
		}
803

    
804
		$snmpdconf .= <<<EOD
805
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
806
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
807

    
808
# These are bsnmp macros not php vars.
809
sysContact      = $(contact)
810
sysLocation     = $(location)
811
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
812

    
813
snmpEnableAuthenTraps = 2
814

    
815
EOD;
816

    
817
		if (is_array( $config['snmpd']['modules'] )) {
818
		    if(isset($config['snmpd']['modules']['mibii'])) {
819
			$snmpdconf .= <<<EOD
820
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
821

    
822
EOD;
823
		    }
824

    
825
		    if(isset($config['snmpd']['modules']['netgraph'])) {
826
			$snmpdconf .= <<<EOD
827
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
828
%netgraph
829
begemotNgControlNodeName = "snmpd"
830

    
831
EOD;
832
		    }
833

    
834
		    if(isset($config['snmpd']['modules']['pf'])) {
835
			$snmpdconf .= <<<EOD
836
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
837

    
838
EOD;
839
		    }
840

    
841
		    if(isset($config['snmpd']['modules']['hostres'])) {
842
			$snmpdconf .= <<<EOD
843
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
844

    
845
EOD;
846
		    }
847
		    if(isset($config['snmpd']['modules']['bridge'])) {
848
			$snmpdconf .= <<<EOD
849
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
850
# config must end with blank line
851

    
852

    
853
EOD;
854
		    }
855
		}
856

    
857
		fwrite($fd, $snmpdconf);
858
		fclose($fd);
859

    
860
		if (isset($config['snmpd']['bindlan'])) {
861
			$bindlan = "";
862
		}
863

    
864
		/* run bsnmpd */
865
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
866
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
867

    
868
		if ($g['booting'])
869
			echo "done.\n";
870
	}
871

    
872
	return 0;
873
}
874

    
875
function services_dnsupdate_process($int = "") {
876
	global $config, $g;
877
	if(isset($config['system']['developerspew'])) {
878
		$mt = microtime();
879
		echo "services_dnsupdate_process() being called $mt\n";
880
	}
881

    
882
	/* Dynamic DNS updating active? */
883
	if (is_array($config['dnsupdates']['dnsupdate'])) {
884
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
885
			if (!isset($dnsupdate['enable']))
886
				continue;
887
			if (!empty($int) && $int != $dnsupdate['interface'])
888
				continue;
889

    
890
			/* determine interface name */
891
			$if = get_real_interface($dnsupdate['interface']);
892
			$wanip = get_interface_ip($dnsupdate['interface']);
893
			if ($wanip) {
894

    
895
				$keyname = $dnsupdate['keyname'];
896
				/* trailing dot */
897
				if (substr($keyname, -1) != ".")
898
					$keyname .= ".";
899

    
900
				$hostname = $dnsupdate['host'];
901
				/* trailing dot */
902
				if (substr($hostname, -1) != ".")
903
					$hostname .= ".";
904

    
905
				/* write private key file
906
				   this is dumb - public and private keys are the same for HMAC-MD5,
907
				   but nsupdate insists on having both */
908
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
909
				$privkey .= <<<EOD
910
Private-key-format: v1.2
911
Algorithm: 157 (HMAC)
912
Key: {$dnsupdate['keydata']}
913

    
914
EOD;
915
				fwrite($fd, $privkey);
916
				fclose($fd);
917

    
918
				/* write public key file */
919
				if ($dnsupdate['keytype'] == "zone") {
920
					$flags = 257;
921
					$proto = 3;
922
				} else if ($dnsupdate['keytype'] == "host") {
923
					$flags = 513;
924
					$proto = 3;
925
				} else if ($dnsupdate['keytype'] == "user") {
926
					$flags = 0;
927
					$proto = 2;
928
				}
929

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

    
934
				/* generate update instructions */
935
				$upinst = "";
936
				if (!empty($dnsupdate['server']))
937
					$upinst .= "server {$dnsupdate['server']}\n";
938
				$upinst .= "update delete {$dnsupdate['host']} A\n";
939
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
940
				$upinst .= "\n";	/* mind that trailing newline! */
941

    
942
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
943
				fwrite($fd, $upinst);
944
				fclose($fd);
945

    
946
				/* invoke nsupdate */
947
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
948
				if (isset($dnsupdate['usetcp']))
949
					$cmd .= " -v";
950
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
951
	
952
				mwexec_bg($cmd);
953
			}
954
		}
955
	}
956

    
957
	return 0;
958
}
959

    
960
function setup_wireless_olsr() {
961
	global $config, $g;
962
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
963
		return;
964
	if(isset($config['system']['developerspew'])) {
965
		$mt = microtime();
966
		echo "setup_wireless_olsr($interface) being called $mt\n";
967
	}
968
	conf_mount_rw();
969
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
970
		$olsr_enable = $olsrd['enable'];
971
		if($olsr_enable <> "on")
972
			return;
973
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
974

    
975
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
976
			$enableannounce .= "\nHna4\n";
977
			$enableannounce .= "{\n";
978
		if($olsrd['announcedynamicroute'])
979
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
980
		if($olsrd['enableannounce'] == "on")
981
			$enableannounce .= "0.0.0.0 0.0.0.0";
982
			$enableannounce .= "\n}\n";
983
		} else {
984
			$enableannounce = "";
985
		}
986

    
987
		$olsr .= <<<EODA
988
#
989
# olsr.org OLSR daemon config file
990
#
991
# Lines starting with a # are discarded
992
#
993
# This file was generated by setup_wireless_olsr() in services.inc
994
#
995

    
996
# This file is an example of a typical
997
# configuration for a mostly static
998
# network(regarding mobility) using
999
# the LQ extention
1000

    
1001
# Debug level(0-9)
1002
# If set to 0 the daemon runs in the background
1003

    
1004
DebugLevel	2
1005

    
1006
# IP version to use (4 or 6)
1007

    
1008
IpVersion	4
1009

    
1010
# Clear the screen each time the internal state changes
1011

    
1012
ClearScreen     yes
1013

    
1014
{$enableannounce}
1015

    
1016
# Should olsrd keep on running even if there are
1017
# no interfaces available? This is a good idea
1018
# for a PCMCIA/USB hotswap environment.
1019
# "yes" OR "no"
1020

    
1021
AllowNoInt	yes
1022

    
1023
# TOS(type of service) value for
1024
# the IP header of control traffic.
1025
# If not set it will default to 16
1026

    
1027
#TosValue	16
1028

    
1029
# The fixed willingness to use(0-7)
1030
# If not set willingness will be calculated
1031
# dynamically based on battery/power status
1032
# if such information is available
1033

    
1034
#Willingness    	4
1035

    
1036
# Allow processes like the GUI front-end
1037
# to connect to the daemon.
1038

    
1039
IpcConnect
1040
{
1041
     # Determines how many simultaneously
1042
     # IPC connections that will be allowed
1043
     # Setting this to 0 disables IPC
1044

    
1045
     MaxConnections  0
1046

    
1047
     # By default only 127.0.0.1 is allowed
1048
     # to connect. Here allowed hosts can
1049
     # be added
1050

    
1051
     Host            127.0.0.1
1052
     #Host            10.0.0.5
1053

    
1054
     # You can also specify entire net-ranges
1055
     # that are allowed to connect. Multiple
1056
     # entries are allowed
1057

    
1058
     #Net             192.168.1.0 255.255.255.0
1059
}
1060

    
1061
# Wether to use hysteresis or not
1062
# Hysteresis adds more robustness to the
1063
# link sensing but delays neighbor registration.
1064
# Used by default. 'yes' or 'no'
1065

    
1066
UseHysteresis	no
1067

    
1068
# Hysteresis parameters
1069
# Do not alter these unless you know
1070
# what you are doing!
1071
# Set to auto by default. Allowed
1072
# values are floating point values
1073
# in the interval 0,1
1074
# THR_LOW must always be lower than
1075
# THR_HIGH.
1076

    
1077
#HystScaling	0.50
1078
#HystThrHigh	0.80
1079
#HystThrLow	0.30
1080

    
1081

    
1082
# Link quality level
1083
# 0 = do not use link quality
1084
# 1 = use link quality for MPR selection
1085
# 2 = use link quality for MPR selection and routing
1086
# Defaults to 0
1087

    
1088
LinkQualityLevel	{$olsrd['enablelqe']}
1089

    
1090
# Link quality window size
1091
# Defaults to 10
1092

    
1093
LinkQualityWinSize	10
1094

    
1095
# Polling rate in seconds(float).
1096
# Default value 0.05 sec
1097

    
1098
Pollrate	0.05
1099

    
1100

    
1101
# TC redundancy
1102
# Specifies how much neighbor info should
1103
# be sent in TC messages
1104
# Possible values are:
1105
# 0 - only send MPR selectors
1106
# 1 - send MPR selectors and MPRs
1107
# 2 - send all neighbors
1108
#
1109
# defaults to 0
1110

    
1111
TcRedundancy	2
1112

    
1113
#
1114
# MPR coverage
1115
# Specifies how many MPRs a node should
1116
# try select to reach every 2 hop neighbor
1117
#
1118
# Can be set to any integer >0
1119
#
1120
# defaults to 1
1121

    
1122
MprCoverage	3
1123

    
1124
# Example plugin entry with parameters:
1125

    
1126
EODA;
1127

    
1128
if($olsrd['enablehttpinfo'] == "on") {
1129
	$olsr .= <<<EODB
1130

    
1131
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1132
{
1133
    PlParam     "port"   "{$olsrd['port']}"
1134
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1135
}
1136

    
1137
EODB;
1138

    
1139
}
1140

    
1141
if($olsrd['enabledsecure'] == "on") {
1142
	$olsr .= <<<EODC
1143

    
1144
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1145
{
1146
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1147
}
1148

    
1149
EODC;
1150

    
1151
}
1152

    
1153
if($olsrd['enabledyngw'] == "on") {
1154

    
1155
	/* unset default route, olsr auto negotiates */
1156
	mwexec("/sbin/route delete default");
1157

    
1158
	$olsr .= <<<EODE
1159

    
1160
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1161
{
1162
    # how often to look for a inet gw, in seconds
1163
    # defaults to 5 secs, if commented out
1164
    PlParam     "Interval"   "{$olsrd['polling']}"
1165

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

    
1176
EODE;
1177

    
1178
}
1179

    
1180
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1181
	$interfaces = explode(',', $conf['iface_array']);
1182
	foreach($interfaces as $interface) {
1183
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1184
$olsr .= <<<EODAD
1185
Interface "{$realinterface}"
1186
{
1187

    
1188
    # Hello interval in seconds(float)
1189
    HelloInterval    2.0
1190

    
1191
    # HELLO validity time
1192
    HelloValidityTime	20.0
1193

    
1194
    # TC interval in seconds(float)
1195
    TcInterval        5.0
1196

    
1197
    # TC validity time
1198
    TcValidityTime	30.0
1199

    
1200
    # MID interval in seconds(float)
1201
    MidInterval	5.0
1202

    
1203
    # MID validity time
1204
    MidValidityTime	30.0
1205

    
1206
    # HNA interval in seconds(float)
1207
    HnaInterval	5.0
1208

    
1209
    # HNA validity time
1210
    HnaValidityTime 	30.0
1211

    
1212
    # When multiple links exist between hosts
1213
    # the weight of interface is used to determine
1214
    # the link to use. Normally the weight is
1215
    # automatically calculated by olsrd based
1216
    # on the characteristics of the interface,
1217
    # but here you can specify a fixed value.
1218
    # Olsrd will choose links with the lowest value.
1219

    
1220
    # Weight 0
1221

    
1222

    
1223
}
1224

    
1225
EODAD;
1226

    
1227
	}
1228
	break;
1229
}
1230
		fwrite($fd, $olsr);
1231
		fclose($fd);
1232
	}
1233

    
1234
	if(is_process_running("olsrd"))
1235
		mwexec("/usr/bin/killall olsrd", true);
1236

    
1237
	sleep(2);
1238

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

    
1241
	conf_mount_ro();
1242
}
1243

    
1244
/* configure cron service */
1245
function configure_cron() {
1246
	global $g, $config;
1247
	conf_mount_rw();
1248
	/* preserve existing crontab entries */
1249
	$crontab_contents = file_get_contents("/etc/crontab");
1250
	$crontab_contents_a = split("\n", $crontab_contents);
1251
	
1252
	for ($i = 0; $i < count($crontab_contents_a); $i++) {
1253
		$item =& $crontab_contents_a[$i];
1254
		if (strpos($item, "# pfSense specific crontab entries") !== false) {
1255
			array_splice($crontab_contents_a, $i - 1);
1256
			break;
1257
		}
1258
	}
1259
	$crontab_contents = implode("\n", $crontab_contents_a) . "\n";
1260
	
1261
	
1262
	if (is_array($config['cron']['item'])) {
1263
		$crontab_contents .= "#\n";
1264
		$crontab_contents .= "# pfSense specific crontab entries\n";
1265
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1266
		$crontab_contents .= "#\n";
1267

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

    
1287
	/* do a HUP kill to force sync changes */
1288
	exec('/bin/pkill -HUP cron');
1289

    
1290
	conf_mount_ro();
1291
}
1292

    
1293
function upnp_action ($action) {
1294
	switch($action) {
1295
		case "start":
1296
			if(file_exists('/var/etc/miniupnpd.conf'))
1297
				mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf');
1298
			break;
1299
		case "stop":
1300
			while((int)exec("pgrep miniupnpd | wc -l") > 0)
1301
				mwexec('killall miniupnpd 2>/dev/null', true);
1302
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1303
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1304
			break;
1305
		case "restart":
1306
			upnp_action('stop');
1307
			upnp_action('start');
1308
			break;
1309
	}
1310
}
1311

    
1312
function upnp_start() {
1313
	global $config, $g;
1314

    
1315
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1316
		return;
1317

    
1318
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1319
		if($g['booting']) {
1320
			echo "Starting UPnP service... ";
1321
			require_once('/usr/local/pkg/miniupnpd.inc');
1322
			sync_package_miniupnpd();
1323
			echo "done.\n";
1324
		}
1325
		else {
1326
			upnp_action('start');
1327
		}
1328
	}
1329
}
1330

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

    
1334
	$is_installed = false;
1335

    
1336
	if(!$config['cron']['item'])
1337
		return;
1338

    
1339
	$x=0;
1340
	foreach($config['cron']['item'] as $item) {
1341
		if(strstr($item['command'], $command)) {
1342
			$is_installed = true;
1343
			break;
1344
		}
1345
		$x++;
1346
	}
1347

    
1348
	if($active) {
1349
		$cron_item = array();
1350
		$cron_item['minute'] = $minute;
1351
		$cron_item['hour'] = $hour;
1352
		$cron_item['mday'] = $monthday;
1353
		$cron_item['month'] = $month;
1354
		$cron_item['wday'] = $weekday;
1355
		$cron_item['who'] = $who;
1356
		$cron_item['command'] = $command;
1357
		if(!$is_installed) {
1358
			$config['cron']['item'][] = $cron_item;
1359
			write_config("Installed cron job for {$command}");
1360
		} else {
1361
			$config['cron']['item'][$x] = $cron_item;
1362
			write_config("Updated cron job for {$command}");
1363
		}
1364
	} else {
1365
		if(($is_installed == true) && ($x > 0)) {
1366
			unset($config['cron']['item'][$x]);
1367
			write_config("Remvoed cron job for {$command}");
1368
		}
1369
	}
1370
	configure_cron();
1371
}
1372

    
1373
?>
(37-37/54)