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
	log_error("DynDns: Running updatedns()");
610

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

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

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

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

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

    
637
			services_dyndns_configure_client($dyndns);
638

    
639
			sleep(1);
640
		}
641

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

    
646
	return 0;
647
}
648

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

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

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

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

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

    
672
		$args = "";
673

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

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

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

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

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

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

    
709
	return $return;
710
}
711

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

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

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

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

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

    
737

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

    
743
EOD;
744

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

    
751
EOD;
752
		}
753
*/
754

    
755

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

    
763

    
764
EOD;
765
		}
766

    
767

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

    
775
EOD;
776

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

    
782
EOD;
783
		}
784
*/
785

    
786

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

    
793
EOD;
794
		}
795

    
796

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

    
800
EOD;
801

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

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

    
812
EOD;
813

    
814
		}
815

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

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

    
825
snmpEnableAuthenTraps = 2
826

    
827
EOD;
828

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

    
834
EOD;
835
		    }
836

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

    
843
EOD;
844
		    }
845

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

    
850
EOD;
851
		    }
852

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

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

    
864

    
865
EOD;
866
		    }
867
		}
868

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

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

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

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

    
884
	return 0;
885
}
886

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

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

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

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

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

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

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

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

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

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

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

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

    
969
	return 0;
970
}
971

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

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

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

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

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

    
1016
DebugLevel	2
1017

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

    
1020
IpVersion	4
1021

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

    
1024
ClearScreen     yes
1025

    
1026
{$enableannounce}
1027

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

    
1033
AllowNoInt	yes
1034

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

    
1039
#TosValue	16
1040

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

    
1046
#Willingness    	4
1047

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

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

    
1057
     MaxConnections  0
1058

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

    
1063
     Host            127.0.0.1
1064
     #Host            10.0.0.5
1065

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

    
1070
     #Net             192.168.1.0 255.255.255.0
1071
}
1072

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

    
1078
UseHysteresis	no
1079

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

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

    
1093

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

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

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

    
1105
LinkQualityWinSize	10
1106

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

    
1110
Pollrate	0.05
1111

    
1112

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

    
1123
TcRedundancy	2
1124

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

    
1134
MprCoverage	3
1135

    
1136
# Example plugin entry with parameters:
1137

    
1138
EODA;
1139

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

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

    
1149
EODB;
1150

    
1151
}
1152

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

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

    
1161
EODC;
1162

    
1163
}
1164

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

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

    
1170
	$olsr .= <<<EODE
1171

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

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

    
1188
EODE;
1189

    
1190
}
1191

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

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

    
1203
    # HELLO validity time
1204
    HelloValidityTime	20.0
1205

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

    
1209
    # TC validity time
1210
    TcValidityTime	30.0
1211

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

    
1215
    # MID validity time
1216
    MidValidityTime	30.0
1217

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

    
1221
    # HNA validity time
1222
    HnaValidityTime 	30.0
1223

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

    
1232
    # Weight 0
1233

    
1234

    
1235
}
1236

    
1237
EODAD;
1238

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

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

    
1249
	sleep(2);
1250

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

    
1253
	conf_mount_ro();
1254
}
1255

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

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

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

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

    
1302
	conf_mount_ro();
1303
}
1304

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

    
1327
function upnp_start() {
1328
	global $config;
1329

    
1330
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1331
		return;
1332

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

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

    
1344
	$is_installed = false;
1345

    
1346
	if(!$config['cron']['item'])
1347
		return;
1348

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

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

    
1383
?>
(44-44/61)