Project

General

Profile

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

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

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

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

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

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

    
34
/*
35
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/bin/pgrep	/bin/sh	/usr/local/sbin/dhcpd	/usr/local/sbin/igmpproxy
36
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/usr/sbin/arp	/sbin/ifconfig	/usr/local/sbin/dnsmasq
37
	pfSense_BUILDER_BINARIES:	/usr/sbin/bsnmpd	/sbin/route	/usr/local/sbin/olsrd
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/miniupnpd	
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 interfaces_staticarp_configure($if) {
456
	global $config, $g;
457
	if(isset($config['system']['developerspew'])) {
458
		$mt = microtime();
459
		echo "interfaces_staticarp_configure($if) being called $mt\n";
460
	}
461

    
462
        $ifcfg = $config['interfaces'][$if];
463

    
464
	if (empty($if) || empty($ifcfg['if']))
465
		return 0;
466

    
467
        /* Enable staticarp, if enabled */
468
        if(isset($config['dhcpd'][$if]['staticarp'])) {
469
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
470
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
471
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
472

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

    
476
                        }
477

    
478
                }
479
        } else {
480
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
481
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
482
        }
483

    
484
        return 0;
485
}
486

    
487
function services_dhcrelay_configure() {
488
	global $config, $g;
489
	if(isset($config['system']['developerspew'])) {
490
		$mt = microtime();
491
		echo "services_dhcrelay_configure() being called $mt\n";
492
	}
493

    
494
	/* kill any running dhcrelay */
495
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
496

    
497
	$dhcrelaycfg =& $config['dhcrelay'];
498

    
499
	/* DHCPRelay enabled on any interfaces? */
500
	if (!isset($dhcrelaycfg['enable']))
501
		return 0;
502

    
503
	if ($g['booting'])
504
		echo "Starting DHCP relay service...";
505
	else
506
		sleep(1);
507

    
508
	$iflist = get_configured_interface_list();
509

    
510
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
511
	foreach ($dhcifaces as $dhcrelayif) {
512
		if (!isset($iflist[$dhcrelayif]) ||
513
			link_interface_to_bridge($dhcrelayif))
514
			continue;
515

    
516
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
517
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
518
	}
519

    
520
	/* 
521
	 * In order for the relay to work, it needs to be active
522
	 * on the interface in which the destination server sits.
523
	 */
524
	$srvips = explode(",", $dhcrelaycfg['server']);
525
	foreach ($srvips as $srcidx => $srvip) {
526
		unset($destif);
527
		foreach ($iflist as $ifname) {
528
			$subnet = get_interface_ip($ifname);
529
			if (!is_ipaddr($subnet))
530
				continue;
531
			$subnet .=  "/" . get_interface_subnet($ifname);
532
			if (ip_in_subnet($srvip, $subnet)) {
533
				$destif = get_real_interface($ifname);
534
				break;
535
			}
536
		}
537
		if (!isset($destif)) {
538
			if (is_array($config['staticroutes']['route'])) {
539
				foreach ($config['staticroutes']['route'] as $rtent) {
540
					if (ip_in_subnet($srvip, $rtent['network'])) {
541
						$a_gateways = return_gateways_array(true);
542
						$destif = $a_gateways[$rtent['gateway']]['interface'];
543
						break;
544
					}
545
				}
546
			}
547
		}
548

    
549
		if (!isset($destif)) {
550
			/* Create a array from the existing route table */
551
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
552
        		array_shift($route_str);
553
        		array_shift($route_str);
554
        		array_shift($route_str);
555
        		array_shift($route_str);
556
        		$route_arr = array();
557
        		foreach($route_str as $routeline) {
558
                		$items = preg_split("/[ ]+/i", $routeline);
559
				if (ip_in_subnet($srvip, $items[0])) {
560
					$destif = trim($items[6]);
561
					break;
562
				}
563
        		}
564
		}
565
	
566
		if (!isset($destif)) {
567
			if (is_array($config['gateways']['gateway_item'])) {
568
				foreach ($config['gateways']['gateway_item'] as $gateway) {
569
					if (isset($gateway['defaultgw'])) {
570
						$a_gateways = return_gateways_array(true);
571
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
572
						break;
573
					}		
574
				}
575
			} else
576
				$destif = get_real_interface("wan");
577
		}
578

    
579
		if (!empty($destif))
580
			$dhcrelayifs[] = $destif;
581
	}
582
	$dhcrelayifs = array_unique($dhcrelayifs);
583

    
584
	/* fire up dhcrelay */
585
	if (empty($dhcrelayifs)) {
586
		log_error("No suitable interface found for running dhcrelay!");
587
		return; /* XXX */
588
	}
589

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

    
592
	if (isset($dhcrelaycfg['agentoption']))
593
		$cmd .=  " -a -m replace";
594

    
595
	$cmd .= " " . implode(" ", $srvips);
596
	mwexec($cmd);
597

    
598
	return 0;
599
}
600

    
601
function services_dyndns_configure_client($conf) {
602

    
603
	if (!isset($conf['enable']))
604
		return;
605

    
606
	/* load up the dyndns.class */
607
	require_once("dyndns.class");
608

    
609
	$dns = new updatedns($dnsService = $conf['type'],
610
		$dnsHost = $conf['host'],
611
		$dnsUser = $conf['username'],
612
		$dnsPass = $conf['password'],
613
		$dnsWilcard = $conf['wildcard'],
614
		$dnsMX = $conf['mx'], 
615
		$dnsIf = "{$conf['interface']}");
616
}
617

    
618
function services_dyndns_configure($int = "") {
619
	global $config, $g;
620
	if(isset($config['system']['developerspew'])) {
621
		$mt = microtime();
622
		echo "services_dyndns_configure() being called $mt\n";
623
	}
624

    
625
	$dyndnscfg = $config['dyndnses']['dyndns'];
626

    
627
	if (is_array($dyndnscfg)) {
628
		if ($g['booting']) 
629
			echo "Starting DynDNS clients...";
630

    
631
		foreach ($dyndnscfg as $dyndns) {
632
			if (!empty($int) && $int != $dyndns['interface'])
633
				continue;
634

    
635
			services_dyndns_configure_client($dyndns);
636

    
637
			sleep(1);
638
		}
639

    
640
		if ($g['booting'])
641
			echo "done.\n";
642
	}
643

    
644
	return 0;
645
}
646

    
647
function services_dnsmasq_configure() {
648
	global $config, $g;
649
	$return = 0;
650
	
651
	if(isset($config['system']['developerspew'])) {
652
		$mt = microtime();
653
		echo "services_dnsmasq_configure() being called $mt\n";
654
	}
655

    
656
	/* kill any running dnsmasq */
657
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
658

    
659
	if (isset($config['dnsmasq']['enable'])) {
660

    
661
		if ($g['booting'])
662
			echo "Starting DNS forwarder...";
663
		else
664
			sleep(1);
665

    
666
		/* generate hosts file */
667
		if(system_hosts_generate()!=0)
668
			$return = 1;
669

    
670
		$args = "";
671

    
672
		if (isset($config['dnsmasq']['regdhcp'])) {
673
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
674
		}
675
		
676
		/* Setup forwarded domains */
677
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
678
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
679
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
680
			}
681
		}
682

    
683
		/* Allow DNS Rebind for forwarded domains */
684
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
685
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
686
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
687
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
688
				}
689
			}
690
		}
691

    
692
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
693
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
694

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

    
698
		if ($g['booting'])
699
			echo "done.\n";
700
	}
701

    
702
	if (!$g['booting']) {
703
		if(services_dhcpd_configure()!=0)
704
			$return = 1;
705
	}
706

    
707
	return $return;
708
}
709

    
710
function services_snmpd_configure() {
711
	global $config, $g;
712
	if(isset($config['system']['developerspew'])) {
713
		$mt = microtime();
714
		echo "services_snmpd_configure() being called $mt\n";
715
	}
716

    
717
	/* kill any running snmpd */
718
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
719
	sleep(2);
720
	if(is_process_running("bsnmpd")) 
721
		mwexec("/usr/bin/killall bsnmpd", true);
722

    
723
	if (isset($config['snmpd']['enable'])) {
724

    
725
		if ($g['booting'])
726
			echo "Starting SNMP daemon... ";
727

    
728
		/* generate snmpd.conf */
729
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
730
		if (!$fd) {
731
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
732
			return 1;
733
		}
734

    
735

    
736
		$snmpdconf = <<<EOD
737
location := "{$config['snmpd']['syslocation']}"
738
contact := "{$config['snmpd']['syscontact']}"
739
read := "{$config['snmpd']['rocommunity']}"
740

    
741
EOD;
742

    
743
/* No docs on what write strings do there for disable for now.
744
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
745
		    $snmpdconf .= <<<EOD
746
# write string
747
write := "{$config['snmpd']['rwcommunity']}"
748

    
749
EOD;
750
		}
751
*/
752

    
753

    
754
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
755
		    $snmpdconf .= <<<EOD
756
# SNMP Trap support.
757
traphost := {$config['snmpd']['trapserver']}
758
trapport := {$config['snmpd']['trapserverport']}
759
trap := "{$config['snmpd']['trapstring']}"
760

    
761

    
762
EOD;
763
		}
764

    
765

    
766
		$snmpdconf .= <<<EOD
767
system := 1     # pfSense
768
%snmpd
769
begemotSnmpdDebugDumpPdus       = 2
770
begemotSnmpdDebugSyslogPri      = 7
771
begemotSnmpdCommunityString.0.1 = $(read)
772

    
773
EOD;
774

    
775
/* No docs on what write strings do there for disable for now.
776
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
777
		    $snmpdconf .= <<<EOD
778
begemotSnmpdCommunityString.0.2 = $(write)
779

    
780
EOD;
781
		}
782
*/
783

    
784

    
785
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
786
		    $snmpdconf .= <<<EOD
787
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
788
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
789
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
790

    
791
EOD;
792
		}
793

    
794

    
795
		$snmpdconf .= <<<EOD
796
begemotSnmpdCommunityDisable    = 1
797

    
798
EOD;
799

    
800
		if(isset($config['snmpd']['bindlan'])) {
801
			$bind_to_ip = get_interface_ip("lan");
802
		} else {
803
			$bind_to_ip = "0.0.0.0";
804
		}
805

    
806
		if(is_port( $config['snmpd']['pollport'] )) {
807
		    $snmpdconf .= <<<EOD
808
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
809

    
810
EOD;
811

    
812
		}
813

    
814
		$snmpdconf .= <<<EOD
815
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
816
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
817

    
818
# These are bsnmp macros not php vars.
819
sysContact      = $(contact)
820
sysLocation     = $(location)
821
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
822

    
823
snmpEnableAuthenTraps = 2
824

    
825
EOD;
826

    
827
		if (is_array( $config['snmpd']['modules'] )) {
828
		    if(isset($config['snmpd']['modules']['mibii'])) {
829
			$snmpdconf .= <<<EOD
830
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
831

    
832
EOD;
833
		    }
834

    
835
		    if(isset($config['snmpd']['modules']['netgraph'])) {
836
			$snmpdconf .= <<<EOD
837
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
838
%netgraph
839
begemotNgControlNodeName = "snmpd"
840

    
841
EOD;
842
		    }
843

    
844
		    if(isset($config['snmpd']['modules']['pf'])) {
845
			$snmpdconf .= <<<EOD
846
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
847

    
848
EOD;
849
		    }
850

    
851
		    if(isset($config['snmpd']['modules']['hostres'])) {
852
			$snmpdconf .= <<<EOD
853
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
854

    
855
EOD;
856
		    }
857
		    if(isset($config['snmpd']['modules']['bridge'])) {
858
			$snmpdconf .= <<<EOD
859
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
860
# config must end with blank line
861

    
862

    
863
EOD;
864
		    }
865
		}
866

    
867
		fwrite($fd, $snmpdconf);
868
		fclose($fd);
869

    
870
		if (isset($config['snmpd']['bindlan'])) {
871
			$bindlan = "";
872
		}
873

    
874
		/* run bsnmpd */
875
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
876
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
877

    
878
		if ($g['booting'])
879
			echo "done.\n";
880
	}
881

    
882
	return 0;
883
}
884

    
885
function services_dnsupdate_process($int = "") {
886
	global $config, $g;
887
	if(isset($config['system']['developerspew'])) {
888
		$mt = microtime();
889
		echo "services_dnsupdate_process() being called $mt\n";
890
	}
891

    
892
	/* Dynamic DNS updating active? */
893
	if (is_array($config['dnsupdates']['dnsupdate'])) {
894
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
895
			if (!isset($dnsupdate['enable']))
896
				continue;
897
			if (!empty($int) && $int != $dnsupdate['interface'])
898
				continue;
899

    
900
			/* determine interface name */
901
			$if = get_real_interface($dnsupdate['interface']);
902
			$wanip = get_interface_ip($dnsupdate['interface']);
903
			if ($wanip) {
904

    
905
				$keyname = $dnsupdate['keyname'];
906
				/* trailing dot */
907
				if (substr($keyname, -1) != ".")
908
					$keyname .= ".";
909

    
910
				$hostname = $dnsupdate['host'];
911
				/* trailing dot */
912
				if (substr($hostname, -1) != ".")
913
					$hostname .= ".";
914

    
915
				/* write private key file
916
				   this is dumb - public and private keys are the same for HMAC-MD5,
917
				   but nsupdate insists on having both */
918
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
919
				$privkey .= <<<EOD
920
Private-key-format: v1.2
921
Algorithm: 157 (HMAC)
922
Key: {$dnsupdate['keydata']}
923

    
924
EOD;
925
				fwrite($fd, $privkey);
926
				fclose($fd);
927

    
928
				/* write public key file */
929
				if ($dnsupdate['keytype'] == "zone") {
930
					$flags = 257;
931
					$proto = 3;
932
				} else if ($dnsupdate['keytype'] == "host") {
933
					$flags = 513;
934
					$proto = 3;
935
				} else if ($dnsupdate['keytype'] == "user") {
936
					$flags = 0;
937
					$proto = 2;
938
				}
939

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

    
944
				/* generate update instructions */
945
				$upinst = "";
946
				if (!empty($dnsupdate['server']))
947
					$upinst .= "server {$dnsupdate['server']}\n";
948
				$upinst .= "update delete {$dnsupdate['host']} A\n";
949
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
950
				$upinst .= "\n";	/* mind that trailing newline! */
951

    
952
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
953
				fwrite($fd, $upinst);
954
				fclose($fd);
955

    
956
				/* invoke nsupdate */
957
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
958
				if (isset($dnsupdate['usetcp']))
959
					$cmd .= " -v";
960
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
961
	
962
				mwexec_bg($cmd);
963
			}
964
		}
965
	}
966

    
967
	return 0;
968
}
969

    
970
function setup_wireless_olsr() {
971
	global $config, $g;
972
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
973
		return;
974
	if(isset($config['system']['developerspew'])) {
975
		$mt = microtime();
976
		echo "setup_wireless_olsr($interface) being called $mt\n";
977
	}
978
	conf_mount_rw();
979
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
980
		$olsr_enable = $olsrd['enable'];
981
		if($olsr_enable <> "on")
982
			return;
983
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
984

    
985
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
986
			$enableannounce .= "\nHna4\n";
987
			$enableannounce .= "{\n";
988
		if($olsrd['announcedynamicroute'])
989
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
990
		if($olsrd['enableannounce'] == "on")
991
			$enableannounce .= "0.0.0.0 0.0.0.0";
992
			$enableannounce .= "\n}\n";
993
		} else {
994
			$enableannounce = "";
995
		}
996

    
997
		$olsr .= <<<EODA
998
#
999
# olsr.org OLSR daemon config file
1000
#
1001
# Lines starting with a # are discarded
1002
#
1003
# This file was generated by setup_wireless_olsr() in services.inc
1004
#
1005

    
1006
# This file is an example of a typical
1007
# configuration for a mostly static
1008
# network(regarding mobility) using
1009
# the LQ extention
1010

    
1011
# Debug level(0-9)
1012
# If set to 0 the daemon runs in the background
1013

    
1014
DebugLevel	2
1015

    
1016
# IP version to use (4 or 6)
1017

    
1018
IpVersion	4
1019

    
1020
# Clear the screen each time the internal state changes
1021

    
1022
ClearScreen     yes
1023

    
1024
{$enableannounce}
1025

    
1026
# Should olsrd keep on running even if there are
1027
# no interfaces available? This is a good idea
1028
# for a PCMCIA/USB hotswap environment.
1029
# "yes" OR "no"
1030

    
1031
AllowNoInt	yes
1032

    
1033
# TOS(type of service) value for
1034
# the IP header of control traffic.
1035
# If not set it will default to 16
1036

    
1037
#TosValue	16
1038

    
1039
# The fixed willingness to use(0-7)
1040
# If not set willingness will be calculated
1041
# dynamically based on battery/power status
1042
# if such information is available
1043

    
1044
#Willingness    	4
1045

    
1046
# Allow processes like the GUI front-end
1047
# to connect to the daemon.
1048

    
1049
IpcConnect
1050
{
1051
     # Determines how many simultaneously
1052
     # IPC connections that will be allowed
1053
     # Setting this to 0 disables IPC
1054

    
1055
     MaxConnections  0
1056

    
1057
     # By default only 127.0.0.1 is allowed
1058
     # to connect. Here allowed hosts can
1059
     # be added
1060

    
1061
     Host            127.0.0.1
1062
     #Host            10.0.0.5
1063

    
1064
     # You can also specify entire net-ranges
1065
     # that are allowed to connect. Multiple
1066
     # entries are allowed
1067

    
1068
     #Net             192.168.1.0 255.255.255.0
1069
}
1070

    
1071
# Wether to use hysteresis or not
1072
# Hysteresis adds more robustness to the
1073
# link sensing but delays neighbor registration.
1074
# Used by default. 'yes' or 'no'
1075

    
1076
UseHysteresis	no
1077

    
1078
# Hysteresis parameters
1079
# Do not alter these unless you know
1080
# what you are doing!
1081
# Set to auto by default. Allowed
1082
# values are floating point values
1083
# in the interval 0,1
1084
# THR_LOW must always be lower than
1085
# THR_HIGH.
1086

    
1087
#HystScaling	0.50
1088
#HystThrHigh	0.80
1089
#HystThrLow	0.30
1090

    
1091

    
1092
# Link quality level
1093
# 0 = do not use link quality
1094
# 1 = use link quality for MPR selection
1095
# 2 = use link quality for MPR selection and routing
1096
# Defaults to 0
1097

    
1098
LinkQualityLevel	{$olsrd['enablelqe']}
1099

    
1100
# Link quality window size
1101
# Defaults to 10
1102

    
1103
LinkQualityWinSize	10
1104

    
1105
# Polling rate in seconds(float).
1106
# Default value 0.05 sec
1107

    
1108
Pollrate	0.05
1109

    
1110

    
1111
# TC redundancy
1112
# Specifies how much neighbor info should
1113
# be sent in TC messages
1114
# Possible values are:
1115
# 0 - only send MPR selectors
1116
# 1 - send MPR selectors and MPRs
1117
# 2 - send all neighbors
1118
#
1119
# defaults to 0
1120

    
1121
TcRedundancy	2
1122

    
1123
#
1124
# MPR coverage
1125
# Specifies how many MPRs a node should
1126
# try select to reach every 2 hop neighbor
1127
#
1128
# Can be set to any integer >0
1129
#
1130
# defaults to 1
1131

    
1132
MprCoverage	3
1133

    
1134
# Example plugin entry with parameters:
1135

    
1136
EODA;
1137

    
1138
if($olsrd['enablehttpinfo'] == "on") {
1139
	$olsr .= <<<EODB
1140

    
1141
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1142
{
1143
    PlParam     "port"   "{$olsrd['port']}"
1144
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1145
}
1146

    
1147
EODB;
1148

    
1149
}
1150

    
1151
if($olsrd['enabledsecure'] == "on") {
1152
	$olsr .= <<<EODC
1153

    
1154
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1155
{
1156
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1157
}
1158

    
1159
EODC;
1160

    
1161
}
1162

    
1163
if($olsrd['enabledyngw'] == "on") {
1164

    
1165
	/* unset default route, olsr auto negotiates */
1166
	mwexec("/sbin/route delete default");
1167

    
1168
	$olsr .= <<<EODE
1169

    
1170
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1171
{
1172
    # how often to look for a inet gw, in seconds
1173
    # defaults to 5 secs, if commented out
1174
    PlParam     "Interval"   "{$olsrd['polling']}"
1175

    
1176
    # if one or more IPv4 addresses are given, do a ping on these in
1177
    # descending order to validate that there is not only an entry in
1178
    # routing table, but also a real internet connection. If any of
1179
    # these addresses could be pinged successfully, the test was
1180
    # succesful, i.e. if the ping on the 1st address was successful,the
1181
    # 2nd won't be pinged
1182
    PlParam     "Ping"       "{$olsrd['ping']}"
1183
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1184
}
1185

    
1186
EODE;
1187

    
1188
}
1189

    
1190
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1191
	$interfaces = explode(',', $conf['iface_array']);
1192
	foreach($interfaces as $interface) {
1193
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1194
$olsr .= <<<EODAD
1195
Interface "{$realinterface}"
1196
{
1197

    
1198
    # Hello interval in seconds(float)
1199
    HelloInterval    2.0
1200

    
1201
    # HELLO validity time
1202
    HelloValidityTime	20.0
1203

    
1204
    # TC interval in seconds(float)
1205
    TcInterval        5.0
1206

    
1207
    # TC validity time
1208
    TcValidityTime	30.0
1209

    
1210
    # MID interval in seconds(float)
1211
    MidInterval	5.0
1212

    
1213
    # MID validity time
1214
    MidValidityTime	30.0
1215

    
1216
    # HNA interval in seconds(float)
1217
    HnaInterval	5.0
1218

    
1219
    # HNA validity time
1220
    HnaValidityTime 	30.0
1221

    
1222
    # When multiple links exist between hosts
1223
    # the weight of interface is used to determine
1224
    # the link to use. Normally the weight is
1225
    # automatically calculated by olsrd based
1226
    # on the characteristics of the interface,
1227
    # but here you can specify a fixed value.
1228
    # Olsrd will choose links with the lowest value.
1229

    
1230
    # Weight 0
1231

    
1232

    
1233
}
1234

    
1235
EODAD;
1236

    
1237
	}
1238
	break;
1239
}
1240
		fwrite($fd, $olsr);
1241
		fclose($fd);
1242
	}
1243

    
1244
	if(is_process_running("olsrd"))
1245
		mwexec("/usr/bin/killall olsrd", true);
1246

    
1247
	sleep(2);
1248

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

    
1251
	conf_mount_ro();
1252
}
1253

    
1254
/* configure cron service */
1255
function configure_cron() {
1256
	global $g, $config;
1257

    
1258
	conf_mount_rw();
1259
	/* preserve existing crontab entries */
1260
	$crontab_contents = file("/etc/crontab", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1261
	
1262
	for ($i = 0; $i < count($crontab_contents); $i++) {
1263
		$cron_item =& $crontab_contents[$i];
1264
		if (strpos($cron_item, "# pfSense specific crontab entries") !== false) {
1265
			array_splice($crontab_contents, $i - 1);
1266
			break;
1267
		}
1268
	}
1269
	$crontab_contents = implode("\n", $crontab_contents) . "\n";
1270
	
1271
	
1272
	if (is_array($config['cron']['item'])) {
1273
		$crontab_contents .= "#\n";
1274
		$crontab_contents .= "# pfSense specific crontab entries\n";
1275
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1276
		$crontab_contents .= "#\n";
1277

    
1278
		foreach ($config['cron']['item'] as $item) {
1279
			$crontab_contents .= "\n{$item['minute']}\t";
1280
			$crontab_contents .= "{$item['hour']}\t";
1281
			$crontab_contents .= "{$item['mday']}\t";
1282
			$crontab_contents .= "{$item['month']}\t";
1283
			$crontab_contents .= "{$item['wday']}\t";
1284
			$crontab_contents .= "{$item['who']}\t";
1285
			$crontab_contents .= "{$item['command']}";
1286
		}
1287
    
1288
		$crontab_contents .= "\n#\n";
1289
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1290
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1291
		$crontab_contents .= "#\n\n";
1292
	}
1293
	
1294
	/* please maintain the newline at the end of file */
1295
	file_put_contents("/etc/crontab", $crontab_contents);
1296

    
1297
	/* do a HUP kill to force sync changes */
1298
	exec('/bin/pkill -HUP cron');
1299

    
1300
	conf_mount_ro();
1301
}
1302

    
1303
function upnp_action ($action) {
1304
	switch($action) {
1305
		case "start":
1306
			if (file_exists('/var/etc/miniupnpd.conf')) {
1307
				@unlink("{$g['varrun_path']}/miniupnpd.pid");
1308
				mwexec_bg("/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf -P {$g['varrun_path']}/miniupnpd.pid");
1309
			}
1310
			break;
1311
		case "stop":
1312
			killbypid("{$g['varrun_path']}/miniupnpd.pid");
1313
			while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0)
1314
				mwexec('killall miniupnpd 2>/dev/null', true);
1315
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1316
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1317
			break;
1318
		case "restart":
1319
			upnp_action('stop');
1320
			upnp_action('start');
1321
			break;
1322
	}
1323
}
1324

    
1325
function upnp_start() {
1326
	global $config;
1327

    
1328
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1329
		return;
1330

    
1331
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1332
		echo "Starting UPnP service... ";
1333
		require_once('/usr/local/pkg/miniupnpd.inc');
1334
		sync_package_miniupnpd();
1335
		echo "done.\n";
1336
	}
1337
}
1338

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

    
1342
	$is_installed = false;
1343

    
1344
	if(!$config['cron']['item'])
1345
		return;
1346

    
1347
	$x=0;
1348
	foreach($config['cron']['item'] as $item) {
1349
		if(strstr($item['command'], $command)) {
1350
			$is_installed = true;
1351
			break;
1352
		}
1353
		$x++;
1354
	}
1355

    
1356
	if($active) {
1357
		$cron_item = array();
1358
		$cron_item['minute'] = $minute;
1359
		$cron_item['hour'] = $hour;
1360
		$cron_item['mday'] = $monthday;
1361
		$cron_item['month'] = $month;
1362
		$cron_item['wday'] = $weekday;
1363
		$cron_item['who'] = $who;
1364
		$cron_item['command'] = $command;
1365
		if(!$is_installed) {
1366
			$config['cron']['item'][] = $cron_item;
1367
			write_config("Installed cron job for {$command}");
1368
		} else {
1369
			$config['cron']['item'][$x] = $cron_item;
1370
			write_config("Updated cron job for {$command}");
1371
		}
1372
	} else {
1373
		if(($is_installed == true) && ($x > 0)) {
1374
			unset($config['cron']['item'][$x]);
1375
			write_config("Remvoed cron job for {$command}");
1376
		}
1377
	}
1378
	configure_cron();
1379
}
1380

    
1381
?>
(44-44/61)