Project

General

Profile

Download (36.4 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
				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_olsr_enabled == true)
232
			if($dhcpifconf['netmask'])
233
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
234

    
235
		$dnscfg = "";
236

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

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

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

    
260
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
261
		$dhcpdconf .= "	pool {\n";
262

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

    
271
		if($dhcpifconf['failover_peerip'] <> "")
272
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
273

    
274
		if (isset($dhcpifconf['denyunknown']))
275
		   $dhcpdconf .= "		deny unknown clients;\n";
276

    
277
		if ($dhcpifconf['gateway'])
278
			$routers = $dhcpifconf['gateway'];
279
		else
280
			$routers = $ifcfgip;
281

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

    
287
		$dhcpdconf .= <<<EOD
288
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
289
	}
290
	option routers {$routers};
291
$dnscfg
292

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

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

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

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

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

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

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

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

    
346
EOD;
347

    
348
		/* add static mappings */
349
		if (is_array($dhcpifconf['staticmap'])) {
350

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

    
357
EOD;
358
				if ($sm['ipaddr'])
359
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
360

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

    
369
				$dhcpdconf .= "}\n";
370
				$i++;
371
			}
372
		}
373

    
374
		$dhcpdifs[] = get_real_interface($dhcpif);
375
	}
376

    
377
	fwrite($fd, $dhcpdconf);
378
	fclose($fd);
379

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

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

    
389
	if ($g['booting']) {
390
		print "done.\n";
391
	}
392

    
393
	return 0;
394
}
395

    
396
function services_igmpproxy_configure() {
397
        global $config, $g;
398

    
399
        $iflist = get_configured_interface_list();
400

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

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

    
407
        $igmpconf = <<<EOD
408

    
409
##------------------------------------------------------
410
## Enable Quickleave mode (Sends Leave instantly)
411
##------------------------------------------------------
412
quickleave
413

    
414
EOD;
415

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

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

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

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

    
448
        return 0;
449
}
450

    
451
function interfaces_staticarp_configure($if) {
452
	global $config, $g;
453
	if(isset($config['system']['developerspew'])) {
454
		$mt = microtime();
455
		echo "interfaces_staticarp_configure($if) being called $mt\n";
456
	}
457

    
458
        $ifcfg = $config['interfaces'][$if];
459

    
460
	if (empty($if) || empty($ifcfg['if']))
461
		return 0;
462

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

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

    
472
                        }
473

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

    
480
        return 0;
481
}
482

    
483
function services_dhcrelay_configure() {
484
	global $config, $g;
485
	if(isset($config['system']['developerspew'])) {
486
		$mt = microtime();
487
		echo "services_dhcrelay_configure() being called $mt\n";
488
	}
489

    
490
	/* kill any running dhcrelay */
491
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
492

    
493
	$dhcrelaycfg =& $config['dhcrelay'];
494

    
495
	/* DHCPRelay enabled on any interfaces? */
496
	if (!isset($dhcrelaycfg['enable']))
497
		return 0;
498

    
499
	if ($g['booting'])
500
		echo "Starting DHCP relay service...";
501
	else
502
		sleep(1);
503

    
504
	$iflist = get_configured_interface_list();
505

    
506
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
507
	foreach ($dhcifaces as $dhcrelayif) {
508
		if (!isset($iflist[$dhcrelayif]) ||
509
			link_interface_to_bridge($dhcrelayif))
510
			continue;
511

    
512
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
513
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
514
	}
515

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

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

    
575
		if (!empty($destif))
576
			$dhcrelayifs[] = $destif;
577
	}
578
	$dhcrelayifs = array_unique($dhcrelayifs);
579

    
580
	/* fire up dhcrelay */
581
	if (empty($dhcrelayifs)) {
582
		log_error("No suitable interface found for running dhcrelay!");
583
		return; /* XXX */
584
	}
585

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

    
588
	if (isset($dhcrelaycfg['agentoption']))
589
		$cmd .=  " -a -m replace";
590

    
591
	$cmd .= " " . implode(" ", $srvips);
592
	mwexec($cmd);
593

    
594
	return 0;
595
}
596

    
597
function services_dyndns_configure_client($conf) {
598

    
599
	if (!isset($conf['enable']))
600
		return;
601

    
602
	/* load up the dyndns.class */
603
	require_once("dyndns.class");
604

    
605
	log_error("DynDns: Running updatedns()");
606

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

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

    
623
	$dyndnscfg = $config['dyndnses']['dyndns'];
624

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

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

    
633
			services_dyndns_configure_client($dyndns);
634

    
635
			sleep(1);
636
		}
637

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

    
642
	return 0;
643
}
644

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

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

    
657
	if (isset($config['dnsmasq']['enable'])) {
658

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

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

    
668
		$args = "";
669

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

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

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

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

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

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

    
705
	return $return;
706
}
707

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

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

    
721
	if (isset($config['snmpd']['enable'])) {
722

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

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

    
733

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

    
739
EOD;
740

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

    
747
EOD;
748
		}
749
*/
750

    
751

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

    
759

    
760
EOD;
761
		}
762

    
763

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

    
771
EOD;
772

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

    
778
EOD;
779
		}
780
*/
781

    
782

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

    
789
EOD;
790
		}
791

    
792

    
793
		$snmpdconf .= <<<EOD
794
begemotSnmpdCommunityDisable    = 1
795

    
796
EOD;
797

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

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

    
808
EOD;
809

    
810
		}
811

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

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

    
821
snmpEnableAuthenTraps = 2
822

    
823
EOD;
824

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

    
830
EOD;
831
		    }
832

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

    
839
EOD;
840
		    }
841

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

    
846
EOD;
847
		    }
848

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

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

    
860

    
861
EOD;
862
		    }
863
		}
864

    
865
		fwrite($fd, $snmpdconf);
866
		fclose($fd);
867

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

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

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

    
880
	return 0;
881
}
882

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

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

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

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

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

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

    
922
EOD;
923
				fwrite($fd, $privkey);
924
				fclose($fd);
925

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

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

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

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

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

    
965
	return 0;
966
}
967

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

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

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

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

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

    
1012
DebugLevel	2
1013

    
1014
# IP version to use (4 or 6)
1015

    
1016
IpVersion	4
1017

    
1018
# Clear the screen each time the internal state changes
1019

    
1020
ClearScreen     yes
1021

    
1022
{$enableannounce}
1023

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

    
1029
AllowNoInt	yes
1030

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

    
1035
#TosValue	16
1036

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

    
1042
#Willingness    	4
1043

    
1044
# Allow processes like the GUI front-end
1045
# to connect to the daemon.
1046

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

    
1053
     MaxConnections  0
1054

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

    
1059
     Host            127.0.0.1
1060
     #Host            10.0.0.5
1061

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

    
1066
     #Net             192.168.1.0 255.255.255.0
1067
}
1068

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

    
1074
UseHysteresis	no
1075

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

    
1085
#HystScaling	0.50
1086
#HystThrHigh	0.80
1087
#HystThrLow	0.30
1088

    
1089

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

    
1096
LinkQualityLevel	{$olsrd['enablelqe']}
1097

    
1098
# Link quality window size
1099
# Defaults to 10
1100

    
1101
LinkQualityWinSize	10
1102

    
1103
# Polling rate in seconds(float).
1104
# Default value 0.05 sec
1105

    
1106
Pollrate	0.05
1107

    
1108

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

    
1119
TcRedundancy	2
1120

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

    
1130
MprCoverage	3
1131

    
1132
# Example plugin entry with parameters:
1133

    
1134
EODA;
1135

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

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

    
1145
EODB;
1146

    
1147
}
1148

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

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

    
1157
EODC;
1158

    
1159
}
1160

    
1161
if($olsrd['enabledyngw'] == "on") {
1162

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

    
1166
	$olsr .= <<<EODE
1167

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

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

    
1184
EODE;
1185

    
1186
}
1187

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

    
1196
    # Hello interval in seconds(float)
1197
    HelloInterval    2.0
1198

    
1199
    # HELLO validity time
1200
    HelloValidityTime	20.0
1201

    
1202
    # TC interval in seconds(float)
1203
    TcInterval        5.0
1204

    
1205
    # TC validity time
1206
    TcValidityTime	30.0
1207

    
1208
    # MID interval in seconds(float)
1209
    MidInterval	5.0
1210

    
1211
    # MID validity time
1212
    MidValidityTime	30.0
1213

    
1214
    # HNA interval in seconds(float)
1215
    HnaInterval	5.0
1216

    
1217
    # HNA validity time
1218
    HnaValidityTime 	30.0
1219

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

    
1228
    # Weight 0
1229

    
1230

    
1231
}
1232

    
1233
EODAD;
1234

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

    
1242
	if(is_process_running("olsrd"))
1243
		mwexec("/usr/bin/killall olsrd", true);
1244

    
1245
	sleep(2);
1246

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

    
1249
	conf_mount_ro();
1250
}
1251

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

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

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

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

    
1298
	conf_mount_ro();
1299
}
1300

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

    
1320
function upnp_start() {
1321
	global $config, $g;
1322

    
1323
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1324
		return;
1325

    
1326
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1327
		if($g['booting']) {
1328
			echo "Starting UPnP service... ";
1329
			require_once('/usr/local/pkg/miniupnpd.inc');
1330
			sync_package_miniupnpd();
1331
			echo "done.\n";
1332
		}
1333
		else {
1334
			upnp_action('start');
1335
		}
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
?>
(37-37/54)