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/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
        $iflist = get_configured_interface_list();
403

    
404
        /* kill any running igmpproxy */
405
        killbyname("igmpproxy");
406

    
407
	if (!is_array($config['igmpproxy']['igmpentry']))
408
		return 1;
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

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

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

    
451
        return 0;
452
}
453

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

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

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

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

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

    
475
                        }
476

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

    
483
        return 0;
484
}
485

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

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

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

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

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

    
507
	$iflist = get_configured_interface_list();
508

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

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

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

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

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

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

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

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

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

    
597
	return 0;
598
}
599

    
600
function services_dyndns_configure_client($conf) {
601

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

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

    
608
	log_error("DynDns: Running updatedns()");
609

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

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

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

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

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

    
636
			services_dyndns_configure_client($dyndns);
637

    
638
			sleep(1);
639
		}
640

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

    
645
	return 0;
646
}
647

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

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

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

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

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

    
671
		$args = "";
672

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

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

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

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

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

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

    
708
	return $return;
709
}
710

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

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

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

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

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

    
736

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

    
742
EOD;
743

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

    
750
EOD;
751
		}
752
*/
753

    
754

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

    
762

    
763
EOD;
764
		}
765

    
766

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

    
774
EOD;
775

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

    
781
EOD;
782
		}
783
*/
784

    
785

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

    
792
EOD;
793
		}
794

    
795

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

    
799
EOD;
800

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

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

    
811
EOD;
812

    
813
		}
814

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

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

    
824
snmpEnableAuthenTraps = 2
825

    
826
EOD;
827

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

    
833
EOD;
834
		    }
835

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

    
842
EOD;
843
		    }
844

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

    
849
EOD;
850
		    }
851

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

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

    
863

    
864
EOD;
865
		    }
866
		}
867

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

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

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

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

    
883
	return 0;
884
}
885

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

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

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

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

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

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

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

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

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

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

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

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

    
968
	return 0;
969
}
970

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

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

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

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

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

    
1015
DebugLevel	2
1016

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

    
1019
IpVersion	4
1020

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

    
1023
ClearScreen     yes
1024

    
1025
{$enableannounce}
1026

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

    
1032
AllowNoInt	yes
1033

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

    
1038
#TosValue	16
1039

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

    
1045
#Willingness    	4
1046

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

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

    
1056
     MaxConnections  0
1057

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

    
1062
     Host            127.0.0.1
1063
     #Host            10.0.0.5
1064

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

    
1069
     #Net             192.168.1.0 255.255.255.0
1070
}
1071

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

    
1077
UseHysteresis	no
1078

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

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

    
1092

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

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

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

    
1104
LinkQualityWinSize	10
1105

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

    
1109
Pollrate	0.05
1110

    
1111

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

    
1122
TcRedundancy	2
1123

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

    
1133
MprCoverage	3
1134

    
1135
# Example plugin entry with parameters:
1136

    
1137
EODA;
1138

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

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

    
1148
EODB;
1149

    
1150
}
1151

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

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

    
1160
EODC;
1161

    
1162
}
1163

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

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

    
1169
	$olsr .= <<<EODE
1170

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

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

    
1187
EODE;
1188

    
1189
}
1190

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

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

    
1202
    # HELLO validity time
1203
    HelloValidityTime	20.0
1204

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

    
1208
    # TC validity time
1209
    TcValidityTime	30.0
1210

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

    
1214
    # MID validity time
1215
    MidValidityTime	30.0
1216

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

    
1220
    # HNA validity time
1221
    HnaValidityTime 	30.0
1222

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

    
1231
    # Weight 0
1232

    
1233

    
1234
}
1235

    
1236
EODAD;
1237

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

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

    
1248
	sleep(2);
1249

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

    
1252
	conf_mount_ro();
1253
}
1254

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

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

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

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

    
1301
	conf_mount_ro();
1302
}
1303

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

    
1323
function upnp_start() {
1324
	global $config;
1325

    
1326
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1327
		return;
1328

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

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

    
1340
	$is_installed = false;
1341

    
1342
	if(!$config['cron']['item'])
1343
		return;
1344

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

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

    
1379
?>
(44-44/61)