Project

General

Profile

Download (46.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/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	/usr/sbin/rtadvd
39
	pfSense_MODULE:	utils
40
*/
41

    
42
/* implement ipv6 route advertising deamon */
43
function services_rtadvd_configure() {
44
	global $config, $g;
45
	
46
	if(isset($config['system']['developerspew'])) {
47
		$mt = microtime();
48
		echo "services_rtadvd_configure() being called $mt\n";
49
	}
50

    
51
	if($g['services_dhcp_server_enable'] == false) 
52
		return;
53

    
54
	if(is_process_running("rtadvd")) {
55
		mwexec("killall -9 rtadvd", true);
56
	}
57

    
58
	/* DHCP enabled on any interfaces? */
59
	if (!is_dhcp_server_enabled())
60
		return 0;
61

    
62
	if (!is_array($config['dhcpdv6']))
63
		$config['dhcpdv6'] = array();
64

    
65
	$dhcpdv6cfg = $config['dhcpdv6'];
66
	$Iflist = get_configured_interface_list();
67

    
68
	/* write rtadvd.conf */
69
	$fd = fopen("{$g['varetc_path']}/rtadvd.conf", "w");
70
	if (!$fd) {
71
		printf("Error: cannot open rtadvd.conf in services_rtadvd_configure().\n");
72
		return 1;
73
	}
74

    
75
	/* raflags, managed=64, stateful=128, both=192 */
76

    
77
	$rtadvdconf = "# Automatically Generated, do not edit\n";
78
	$rtadvdnum = 0;
79
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
80
		$rtadvdnum++;
81
		/* It appears we can not advertise the gateway IP (carp)
82
		 * 	rtadvd[44205]: <sock_open> IPV6_JOIN_GROUP(link) on vip1: Can't assign requested address
83
		if($dhcpv6ifconf['gateway'] <> "") {
84
			$dhcpv6if = find_carp_interface($dhcpv6ifconf['gateway']);
85
		}
86
		*/
87
		$realif = get_real_interface($dhcpv6if);
88

    
89
		$rtadvdifs[] = $realif;
90

    
91
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
92
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
93
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
94
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
95

    
96
		$rtadvdconf .= "{$realif}:\\\n";
97
		$rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
98
		$rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
99
		$rtadvdconf .= "\t:raflags#192:\n";
100
		$rtadvdconf .= "\n";
101

    
102
	}
103

    
104
	fwrite($fd, $rtadvdconf);
105
	fclose($fd);
106

    
107
	if(count($rtadvdifs) > 0) {
108
		mwexec("/usr/sbin/rtadvd -c {$g['varetc_path']}/rtadvd.conf " . join(" ", $rtadvdifs));
109
	}
110
	return 0;
111
}
112

    
113
function services_dhcpd_configure() {
114
	global $config, $g;
115
	
116
	if($g['services_dhcp_server_enable'] == false) 
117
		return;
118

    
119
	if(isset($config['system']['developerspew'])) {
120
		$mt = microtime();
121
		echo "services_dhcpd_configure($if) being called $mt\n";
122
	}
123
	
124
	/* kill any running dhcpd */
125
	if(is_process_running("dhcpd")) {
126
		mwexec("killall dhcpd", true);
127
	}
128

    
129
	/* DHCP enabled on any interfaces? */
130
	if (!is_dhcp_server_enabled())
131
		return 0;
132

    
133
	/* if OLSRD is enabled, allow WAN to house DHCP. */
134
	if($config['installedpackages']['olsrd'])
135
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
136
				if($olsrd['enable'])
137
					$is_olsr_enabled = true;
138

    
139
	/* configure DHCPD chroot */
140
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
141
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
142
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
143
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
144
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
145
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
146
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
147
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");	
148
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
149
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
150
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
151
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
152
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
153
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
154
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
155
	if(!trim($status))
156
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
157
	fclose($fd);
158
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
159

    
160
	if ($g['booting']) {
161
		if ($g['platform'] != "pfSense") {
162
			/* restore the leases, if we have them */
163
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
164
				$dhcprestore = "";
165
				$dhcpreturn = "";
166
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
167
				$dhcprestore = implode(" ", $dhcprestore);
168
				if($dhcpreturn <> 0) {
169
					log_error("DHCP leases restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
170
				}
171
			}
172
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
173
				$dhcprestore = "";
174
				$dhcpreturn = "";
175
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
176
				$dhcprestore = implode(" ", $dhcprestore);
177
				if($dhcpreturn <> 0) {
178
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
179
				}
180
			}
181
		}
182
	}
183

    
184
	$syscfg = $config['system'];
185
	if (!is_array($config['dhcpd']))
186
		$config['dhcpd'] = array();
187
	if (!is_array($config['dhcpdv6']))
188
		$config['dhcpdv6'] = array();
189
	$dhcpdcfg = $config['dhcpd'];
190
	$dhcpdv6cfg = $config['dhcpdv6'];
191
	$Iflist = get_configured_interface_list();
192
		
193
	if ($g['booting'])
194
		echo "Starting DHCP service...";
195
	else
196
		sleep(1);
197

    
198
	/* write dhcpd.conf */
199
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
200
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
201
	if ((!$fd) || (! $fdv6)) {
202
		printf("Error: cannot open dhcpd.conf or dhcpdv6.conf in services_dhcpd_configure().\n");
203
		return 1;
204
	}
205

    
206
	$custoptions = "";
207
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
208
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
209
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
210
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = text;\n";
211
			}
212
		}
213
	}
214
	$custoptionsv6 = "";
215
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {	
216
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
217
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
218
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
219
			}
220
		}
221
	}
222

    
223
	$dhcpdconf = <<<EOD
224
	
225
option domain-name "{$syscfg['domain']}";
226
option ldap-server code 95 = text;
227
option domain-search-list code 119 = text;
228
{$custoptions}
229
default-lease-time 7200;
230
max-lease-time 86400;
231
log-facility local7;
232
ddns-update-style none;
233
one-lease-per-client true;
234
deny duplicates;
235
ping-check true;
236

    
237
EOD;
238

    
239
	$dhcpdv6conf = <<<EOD
240
	
241
option domain-name "{$syscfg['domain']}";
242
option ldap-server code 95 = text;
243
option domain-search-list code 119 = text;
244
{$custoptions}
245
default-lease-time 7200;
246
max-lease-time 86400;
247
log-facility local7;
248
ddns-update-style none;
249
one-lease-per-client true;
250
deny duplicates;
251
ping-check true;
252

    
253
EOD;
254

    
255
	if(!isset($dhcpifconf['disableauthoritative']))
256
		$dhcpdconf .= "authoritative;\n";
257
	if(!isset($dhcpv6ifconf['disableauthoritative']))
258
		$dhcpdv6conf .= "authoritative;\n";
259

    
260
	if(isset($dhcpifconf['alwaysbroadcast'])) 
261
		$dhcpdconf .= "always-broadcast on\n";
262
	if(isset($dhcpv6ifconf['alwaysbroadcast'])) 
263
		$dhcpdv6conf .= "always-broadcast on\n";
264

    
265
	$dhcpdifs = array();
266
	$dhcpdv6ifs = array();
267

    
268
	/*    loop through and determine if we need to setup
269
	 *    failover peer "bleh" entries
270
	 */
271
	$dhcpnum = 0;
272
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
273

    
274
		interfaces_staticarp_configure($dhcpif);
275

    
276
		if (!isset($dhcpifconf['enable']))
277
			continue;
278

    
279
		if($dhcpifconf['failover_peerip'] <> "") {
280
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
281
			$intip = find_interface_ip($int);
282
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
283
			/*
284
			 *    yep, failover peer is defined.
285
			 *    does it match up to a defined vip?
286
			 */
287
			$skew = 110;
288
			$a_vip = &$config['virtualip']['vip'];
289
			if(is_array($a_vip)) {
290
				foreach ($a_vip as $vipent) {
291
					if($int == $real_dhcpif) {
292
						/* this is the interface! */
293
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
294
							$skew = 0;
295
					}
296
				}
297
			} else {
298
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
299
			}
300
			if($skew > 10) {
301
				$type = "secondary";
302
				$dhcpdconf_pri  = "mclt 600;\n";
303
				$my_port = "520";
304
				$peer_port = "519";
305
			} else {
306
				$my_port = "519";
307
				$peer_port = "520";
308
				$type = "primary";
309
				$dhcpdconf_pri  = "split 128;\n";
310
				$dhcpdconf_pri .= "  mclt 600;\n";
311
			}
312
			$dhcpdconf .= <<<EOPP
313
failover peer "dhcp{$dhcpnum}" {
314
  {$type};
315
  address {$intip};
316
  port {$my_port};
317
  peer address {$dhcpifconf['failover_peerip']};
318
  peer port {$peer_port};
319
  max-response-delay 10;
320
  max-unacked-updates 10;
321
  {$dhcpdconf_pri}
322
  load balance max seconds 3;
323
}
324

    
325
EOPP;
326
		$dhcpnum++;
327
		}
328
	}
329
	$dhcpv6num = 0;
330
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
331

    
332
		interfaces_staticarp_configure($dhcpv6if);
333

    
334
		if (!isset($dhcpv6ifconf['enable']))
335
			continue;
336

    
337
		if($dhcpv6ifconf['failover_peerip'] <> "") {
338
			$intv6 = guess_interface_from_ipv6($dhcpv6ifconf['failover_peerip']);
339
			$intipv6 = find_interface_ipv6($intv6);
340
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
341
			/*
342
			 *    yep, failover peer is defined.
343
			 *    does it match up to a defined vip?
344
			 */
345
			$skew = 110;
346
			$a_vip = &$config['virtualip']['vip'];
347
			if(is_array($a_vip)) {
348
				foreach ($a_vip as $vipent) {
349
					if($intv6 == $real_dhcpv6if) {
350
						/* this is the interface! */
351
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
352
							$skew = 0;
353
					}
354
				}
355
			} else {
356
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
357
			}
358
			if($skew > 10) {
359
				$typev6 = "secondary";
360
				$dhcpdv6conf_pri  = "mclt 600;\n";
361
				$my_portv6 = "520";
362
				$peer_portv6 = "519";
363
			} else {
364
				$my_portv6 = "519";
365
				$peer_portv6 = "520";
366
				$typev6 = "primary";
367
				$dhcpdv6conf_pri  = "split 128;\n";
368
				$dhcpdv6conf_pri .= "  mclt 600;\n";
369
			}
370
			$dhcpdv6conf .= <<<EOPP
371
failover peer "dhcpv6{$dhcpv6num}" {
372
  {$typev6};
373
  address {$intipv6};
374
  port {$my_portv6};
375
  peer address {$dhcpv6ifconf['failover_peerip']};
376
  peer port {$peer_portv6};
377
  max-response-delay 10;
378
  max-unacked-updates 10;
379
  {$dhcpdv6conf_pri}
380
  load balance max seconds 3;
381
}
382

    
383
EOPP;
384
		$dhcpv6num++;
385
		}
386
	}
387

    
388
	$dhcpnum = 0;
389

    
390
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
391

    
392
		$ifcfg = $config['interfaces'][$dhcpif];
393

    
394
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
395
			continue;
396
		$ifcfgip = get_interface_ip($dhcpif);
397
		$ifcfgsn = get_interface_subnet($dhcpif);
398
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
399
		$subnetmask = gen_subnet_mask($ifcfgsn);
400

    
401
		if($is_olsr_enabled == true)
402
			if($dhcpifconf['netmask'])
403
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
404

    
405
		$dnscfg = "";
406

    
407
		if ($dhcpifconf['domain']) {
408
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
409
		}
410
		
411
    		if($dhcpifconf['domainsearchlist'] <> "") {
412
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
413
    		}
414

    
415
		if (isset($dhcpifconf['ddnsupdate'])) {
416
			if($dhcpifconf['ddnsdomain'] <> "") {
417
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
418
			}
419
			$dnscfg .= "	ddns-update-style interim;\n";
420
		}
421

    
422
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
423
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
424
		} else if (isset($config['dnsmasq']['enable'])) {
425
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
426
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
427
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
428
		}
429

    
430
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
431
		$dhcpdconf .= "	pool {\n";
432

    
433
		/* is failover dns setup? */
434
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
435
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
436
			if($dhcpifconf['dnsserver'][1] <> "")
437
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
438
			$dhcpdconf .= ";\n";
439
		}
440

    
441
		if($dhcpifconf['failover_peerip'] <> "")
442
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
443

    
444
		if (isset($dhcpifconf['denyunknown']))
445
		   $dhcpdconf .= "		deny unknown clients;\n";
446

    
447
		if ($dhcpifconf['gateway'])
448
			$routers = $dhcpifconf['gateway'];
449
		else
450
			$routers = $ifcfgip;
451

    
452
		if($dhcpifconf['failover_peerip'] <> "") {
453
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
454
			$dhcpnum++;
455
		}
456

    
457
		$dhcpdconf .= <<<EOD
458
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
459
	}
460
	option routers {$routers};
461
$dnscfg
462

    
463
EOD;
464
    		// default-lease-time
465
		if ($dhcpifconf['defaultleasetime'])
466
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
467

    
468
		// max-lease-time
469
		if ($dhcpifconf['maxleasetime'])
470
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
471

    
472
		// netbios-name*
473
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
474
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
475
			$dhcpdconf .= "	option netbios-node-type 8;\n";
476
		}
477

    
478
		// ntp-servers
479
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
480
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
481

    
482
		// tftp-server-name
483
		if ($dhcpifconf['tftp'] <> "")
484
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
485

    
486
		// Handle option, number rowhelper values
487
		$dhcpdconf .= "\n";
488
		if($dhcpifconf['numberoptions']['item']) {
489
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
490
				$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
491
			}
492
		}
493

    
494
		// ldap-server
495
		if ($dhcpifconf['ldap'] <> "")
496
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
497

    
498
		// net boot information
499
		if(isset($dhcpifconf['netboot'])) {
500
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
501
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
502
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
503
			}
504
			if ($dhcpifconf['rootpath'] <> "") {
505
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
506
      		}
507
		}
508
		
509
		$dhcpdconf .= <<<EOD
510
}
511

    
512
EOD;
513

    
514
		/* add static mappings */
515
		if (is_array($dhcpifconf['staticmap'])) {
516

    
517
			$i = 0;
518
			foreach ($dhcpifconf['staticmap'] as $sm) {
519
				$dhcpdconf .= <<<EOD
520
host s_{$dhcpif}_{$i} {
521
	hardware ethernet {$sm['mac']};
522

    
523
EOD;
524
				if ($sm['ipaddr'])
525
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
526

    
527
				if ($sm['hostname']) {
528
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
529
					$dhhostname = str_replace(".", "_", $dhhostname);
530
					$dhcpdconf .= "	option host-name {$dhhostname};\n";
531
				}
532
				if ($sm['netbootfile'])
533
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
534

    
535
				$dhcpdconf .= "}\n";
536
				$i++;
537
			}
538
		}
539

    
540
		$dhcpdifs[] = get_real_interface($dhcpif);
541
	}
542

    
543
	$dhcpv6num = 0;
544
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
545

    
546
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
547

    
548
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
549
			continue;
550
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
551
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
552
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
553
		$subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
554

    
555
		if($is_olsr_enabled == true)
556
			if($dhcpv6ifconf['netmask'])
557
				$subnetmask = gen_subnet_mask($dhcpv6ifconf['netmask']);
558

    
559
		$dnscfgv6 = "";
560

    
561
		if ($dhcpv6ifconf['domain']) {
562
			$dnscfgv6 .= "	option dhcp6.domain-name \"{$dhcpv6ifconf['domain']}\";\n";
563
		}
564
		
565
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
566
			$dnscfgv6 .= "	option dhcp6.domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
567
    		}
568

    
569
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
570
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
571
				$dnscfgv6 .= "	dhcp6.ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
572
			}
573
			$dnscfgv6 .= "	dhcp6.ddns-update-style interim;\n";
574
		}
575

    
576
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
577
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
578
		} else if (isset($config['dnsmasq']['enable'])) {
579
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
580
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
581
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $syscfg['dnsserver']) . ";";
582
		}
583

    
584
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
585
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
586

    
587
		/* is failover dns setup? */
588
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
589
			$dhcpdv6conf .= "		option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}";
590
			if($dhcpv6ifconf['dnsserver'][1] <> "")
591
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
592
			$dhcpdv6conf .= ";\n";
593
		}
594

    
595
		if($dhcpv6ifconf['failover_peerip'] <> "")
596
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
597

    
598
		if (isset($dhcpv6ifconf['denyunknown']))
599
		   $dhcpdv6conf .= "		deny unknown clients;\n";
600

    
601
		if ($dhcpv6ifconf['gateway'])
602
			$routersv6 = $dhcpv6ifconf['gateway'];
603
		else
604
			$routersv6 = $ifcfgipv6;
605

    
606
		if($dhcpv6ifconf['failover_peerip'] <> "") {
607
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
608
			$dhcpv6num++;
609
		}
610

    
611
		$dhcpdv6conf .= <<<EOD
612
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
613
	# Not supported in IPv6; option dhcp6.routers {$routersv6};
614
$dnscfgv6
615

    
616
EOD;
617
    		// default-lease-time
618
		if ($dhcpv6ifconf['defaultleasetime'])
619
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
620

    
621
		// max-lease-time
622
		if ($dhcpv6ifconf['maxleasetime'])
623
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
624

    
625
		// netbios-name*
626
		if (is_array($dhcpv6ifconf['winsserver']) && $dhcpv6ifconf['winsserver'][0]) {
627
			$dhcpdv6conf .= "	option netbios-name-servers " . join(",", $dhcpv6ifconf['winsserver']) . ";\n";
628
			$dhcpdv6conf .= "	option netbios-node-type 8;\n";
629
		}
630

    
631
		// ntp-servers
632
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0])
633
			$dhcpdv6conf .= "	option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
634

    
635
		// tftp-server-name
636
		if ($dhcpv6ifconf['tftp'] <> "")
637
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
638

    
639
		// Handle option, number rowhelper values
640
		$dhcpdv6conf .= "\n";
641
		if($dhcpv6ifconf['numberoptions']['item']) {
642
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
643
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
644
			}
645
		}
646

    
647
		// ldap-server
648
		if ($dhcpv6ifconf['ldap'] <> "")
649
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
650

    
651
		// net boot information
652
		if(isset($dhcpv6ifconf['netboot'])) {
653
			if (($dhcpv6ifconf['next-server'] <> "") && ($dhcpv6ifconf['filename'] <> "")) {
654
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['next-server']};\n";
655
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
656
			}
657
			if ($dhcpv6ifconf['rootpath'] <> "") {
658
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
659
      		}
660
	}
661
		
662
		$dhcpdv6conf .= <<<EOD
663
}
664
EOD;
665

    
666
		/* add static mappings */
667
		if (is_array($dhcpv6ifconf['staticmap'])) {
668

    
669
			$i = 0;
670
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
671
				$dhcpdv6conf .= <<<EOD
672
host s_{$dhcpv6if}_{$i} {
673
	hardware ethernet {$sm['mac']};
674

    
675
EOD;
676
				if ($sm['ipaddr'])
677
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddr']};\n";
678

    
679
				if ($sm['hostname']) {
680
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
681
					$dhhostname = str_replace(".", "_", $dhhostname);
682
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
683
				}
684
				if ($sm['netbootfile'])
685
					$dhcpdv6conf .= "	filename \"{$sm['netbootfile']}\";\n";
686

    
687
				$dhcpdv6conf .= "}\n";
688
				$i++;
689
			}
690
		}
691

    
692
		$dhcpdv6ifs[] = get_real_interface($dhcpv6if);
693
	}
694

    
695
	fwrite($fd, $dhcpdconf);
696
	fclose($fd);
697
	fwrite($fdv6, $dhcpdv6conf);
698
	fclose($fdv6);
699

    
700
	/* create an empty leases database */
701
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
702
	touch("{$g['varrun_path']}/dhcpd.pid");
703
	/* create an empty leases v6 database */
704
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
705
	touch("{$g['varrun_path']}/dhcpdv6.pid");
706
	
707

    
708
	/* fire up dhcpd in a chroot */
709
	if(count($dhcpdifs) > 0) {
710
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf " .
711
			join(" ", $dhcpdifs));
712
	}
713

    
714
	if(count($dhcpdv6ifs) > 0) {
715
		mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf " .
716
			join(" ", $dhcpdv6ifs));
717
		mwexec("/usr/sbin/rtadvd " . join(" ", $dhcpdv6ifs));
718
	}
719

    
720
	/* start ipv6 route advertising if required */
721
	services_rtadvd_configure();
722

    
723
	if ($g['booting']) {
724
		print "done.\n";
725
	}
726

    
727
	return 0;
728
}
729

    
730
function services_igmpproxy_configure() {
731
        global $config, $g;
732

    
733
        $iflist = get_configured_interface_list();
734

    
735
        /* kill any running igmpproxy */
736
        killbyname("igmpproxy");
737

    
738
	if (!is_array($config['igmpproxy']['igmpentry']))
739
		return 1;
740

    
741
        $igmpconf = <<<EOD
742

    
743
##------------------------------------------------------
744
## Enable Quickleave mode (Sends Leave instantly)
745
##------------------------------------------------------
746
quickleave
747

    
748
EOD;
749

    
750
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
751
                unset($iflist[$igmpcf['ifname']]);
752
                $realif = get_real_interface($igmpcf['ifname']);
753
                if (empty($igmpcf['threshold']))
754
                        $threshld = 1;
755
                else
756
                        $threshld = $igmpcf['threshold'];
757
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
758

    
759
                if ($igmpcf['address'] <> "") {
760
                        $item = explode(" ", $igmpcf['address']);
761
                        foreach($item as $iww)
762
                                $igmpconf .= "altnet {$iww}\n";
763
                }
764
                $igmpconf .= "\n";
765
        }
766
        foreach ($iflist as $ifn) {
767
                $realif = get_real_interface($ifn);
768
                $igmpconf .= "phyint {$realif} disabled\n";
769
        }
770

    
771
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
772
        if (!$igmpfl) {
773
                log_error("Could not write Igmpproxy configuration file!");
774
                return;
775
        }
776
        fwrite($igmpfl, $igmpconf);
777
        fclose($igmpfl);
778

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

    
782
        return 0;
783
}
784

    
785
function interfaces_staticarp_configure($if) {
786
	global $config, $g;
787
	if(isset($config['system']['developerspew'])) {
788
		$mt = microtime();
789
		echo "interfaces_staticarp_configure($if) being called $mt\n";
790
	}
791

    
792
        $ifcfg = $config['interfaces'][$if];
793

    
794
	if (empty($if) || empty($ifcfg['if']))
795
		return 0;
796

    
797
        /* Enable staticarp, if enabled */
798
        if(isset($config['dhcpd'][$if]['staticarp'])) {
799
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
800
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
801
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
802

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

    
806
                        }
807

    
808
                }
809
        } else {
810
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
811
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
812
        }
813

    
814
        return 0;
815
}
816

    
817
function services_dhcrelay_configure() {
818
	global $config, $g;
819
	if(isset($config['system']['developerspew'])) {
820
		$mt = microtime();
821
		echo "services_dhcrelay_configure() being called $mt\n";
822
	}
823

    
824
	/* kill any running dhcrelay */
825
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
826

    
827
	$dhcrelaycfg =& $config['dhcrelay'];
828

    
829
	/* DHCPRelay enabled on any interfaces? */
830
	if (!isset($dhcrelaycfg['enable']))
831
		return 0;
832

    
833
	if ($g['booting'])
834
		echo "Starting DHCP relay service...";
835
	else
836
		sleep(1);
837

    
838
	$iflist = get_configured_interface_list();
839

    
840
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
841
	foreach ($dhcifaces as $dhcrelayif) {
842
		if (!isset($iflist[$dhcrelayif]) ||
843
			link_interface_to_bridge($dhcrelayif))
844
			continue;
845

    
846
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
847
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
848
	}
849

    
850
	/* 
851
	 * In order for the relay to work, it needs to be active
852
	 * on the interface in which the destination server sits.
853
	 */
854
	$srvips = explode(",", $dhcrelaycfg['server']);
855
	foreach ($srvips as $srcidx => $srvip) {
856
		unset($destif);
857
		foreach ($iflist as $ifname) {
858
			$subnet = get_interface_ip($ifname);
859
			if (!is_ipaddr($subnet))
860
				continue;
861
			$subnet .=  "/" . get_interface_subnet($ifname);
862
			if (ip_in_subnet($srvip, $subnet)) {
863
				$destif = get_real_interface($ifname);
864
				break;
865
			}
866
		}
867
		if (!isset($destif)) {
868
			if (is_array($config['staticroutes']['route'])) {
869
				foreach ($config['staticroutes']['route'] as $rtent) {
870
					if (ip_in_subnet($srvip, $rtent['network'])) {
871
						$a_gateways = return_gateways_array(true);
872
						$destif = $a_gateways[$rtent['gateway']]['interface'];
873
						break;
874
					}
875
				}
876
			}
877
		}
878

    
879
		if (!isset($destif)) {
880
			/* Create a array from the existing route table */
881
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
882
        		array_shift($route_str);
883
        		array_shift($route_str);
884
        		array_shift($route_str);
885
        		array_shift($route_str);
886
        		$route_arr = array();
887
        		foreach($route_str as $routeline) {
888
                		$items = preg_split("/[ ]+/i", $routeline);
889
				if (ip_in_subnet($srvip, $items[0])) {
890
					$destif = trim($items[2]);
891
					break;
892
				}
893
        		}
894
		}
895
	
896
		if (!isset($destif)) {
897
			if (is_array($config['gateways']['gateway_item'])) {
898
				foreach ($config['gateways']['gateway_item'] as $gateway) {
899
					if (isset($gateway['defaultgw'])) {
900
						$a_gateways = return_gateways_array(true);
901
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
902
						break;
903
					}		
904
				}
905
			} else
906
				$destif = get_real_interface("wan");
907
		}
908

    
909
		if (!empty($destif))
910
			$dhcrelayifs[] = $destif;
911
	}
912
	$dhcrelayifs = array_unique($dhcrelayifs);
913

    
914
	/* fire up dhcrelay */
915
	if (empty($dhcrelayifs)) {
916
		log_error("No suitable interface found for running dhcrelay!");
917
		return; /* XXX */
918
	}
919

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

    
922
	if (isset($dhcrelaycfg['agentoption']))
923
		$cmd .=  " -a -m replace";
924

    
925
	$cmd .= " " . implode(" ", $srvips);
926
	mwexec($cmd);
927

    
928
	return 0;
929
}
930

    
931
function services_dyndns_configure_client($conf) {
932

    
933
	if (!isset($conf['enable']))
934
		return;
935

    
936
	/* load up the dyndns.class */
937
	require_once("dyndns.class");
938

    
939
	log_error("DynDns: Running updatedns()");
940

    
941
	$dns = new updatedns($dnsService = $conf['type'],
942
		$dnsHost = $conf['host'],
943
		$dnsUser = $conf['username'],
944
		$dnsPass = $conf['password'],
945
		$dnsWilcard = $conf['wildcard'],
946
		$dnsMX = $conf['mx'], 
947
		$dnsIf = "{$conf['interface']}");
948

    
949
}
950

    
951
function services_dyndns_configure($int = "") {
952
	global $config, $g;
953
	if(isset($config['system']['developerspew'])) {
954
		$mt = microtime();
955
		echo "services_dyndns_configure() being called $mt\n";
956
	}
957

    
958
	$dyndnscfg = $config['dyndnses']['dyndns'];
959

    
960
	if (is_array($dyndnscfg)) {
961
		if ($g['booting']) 
962
			echo "Starting DynDNS clients...";
963

    
964
		foreach ($dyndnscfg as $dyndns) {
965
			if (!empty($int) && $int != $dyndns['interface'])
966
				continue;
967

    
968
			services_dyndns_configure_client($dyndns);
969

    
970
			sleep(1);
971
		}
972

    
973
		if ($g['booting'])
974
			echo "done.\n";
975
	}
976

    
977
	return 0;
978
}
979

    
980
function services_dnsmasq_configure() {
981
	global $config, $g;
982
	$return = 0;
983
	
984
	if(isset($config['system']['developerspew'])) {
985
		$mt = microtime();
986
		echo "services_dnsmasq_configure() being called $mt\n";
987
	}
988

    
989
	/* kill any running dnsmasq */
990
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
991

    
992
	if (isset($config['dnsmasq']['enable'])) {
993

    
994
		if ($g['booting'])
995
			echo "Starting DNS forwarder...";
996
		else
997
			sleep(1);
998

    
999
		/* generate hosts file */
1000
		if(system_hosts_generate()!=0)
1001
			$return = 1;
1002

    
1003
		$args = "";
1004

    
1005
		if (isset($config['dnsmasq']['regdhcp'])) {
1006
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
1007
		}
1008
		
1009
		/* Setup forwarded domains */
1010
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1011
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
1012
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
1013
			}
1014
		}
1015

    
1016
		/* Allow DNS Rebind for forwarded domains */
1017
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
1018
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
1019
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
1020
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
1021
				}
1022
			}
1023
		}
1024

    
1025
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
1026
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
1027

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

    
1031
		if ($g['booting'])
1032
			echo "done.\n";
1033
	}
1034

    
1035
	if (!$g['booting']) {
1036
		if(services_dhcpd_configure()!=0)
1037
			$return = 1;
1038
	}
1039

    
1040
	return $return;
1041
}
1042

    
1043
function services_snmpd_configure() {
1044
	global $config, $g;
1045
	if(isset($config['system']['developerspew'])) {
1046
		$mt = microtime();
1047
		echo "services_snmpd_configure() being called $mt\n";
1048
	}
1049

    
1050
	/* kill any running snmpd */
1051
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
1052
	if(is_process_running("bsnmpd")) 
1053
		mwexec("/usr/bin/killall bsnmpd", true);
1054

    
1055
	if (isset($config['snmpd']['enable'])) {
1056

    
1057
		if ($g['booting'])
1058
			echo "Starting SNMP daemon... ";
1059

    
1060
		/* generate snmpd.conf */
1061
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
1062
		if (!$fd) {
1063
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
1064
			return 1;
1065
		}
1066

    
1067

    
1068
		$snmpdconf = <<<EOD
1069
location := "{$config['snmpd']['syslocation']}"
1070
contact := "{$config['snmpd']['syscontact']}"
1071
read := "{$config['snmpd']['rocommunity']}"
1072

    
1073
EOD;
1074

    
1075
/* No docs on what write strings do there for disable for now.
1076
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1077
		    $snmpdconf .= <<<EOD
1078
# write string
1079
write := "{$config['snmpd']['rwcommunity']}"
1080

    
1081
EOD;
1082
		}
1083
*/
1084

    
1085

    
1086
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1087
		    $snmpdconf .= <<<EOD
1088
# SNMP Trap support.
1089
traphost := {$config['snmpd']['trapserver']}
1090
trapport := {$config['snmpd']['trapserverport']}
1091
trap := "{$config['snmpd']['trapstring']}"
1092

    
1093

    
1094
EOD;
1095
		}
1096

    
1097

    
1098
		$snmpdconf .= <<<EOD
1099
system := 1     # pfSense
1100
%snmpd
1101
begemotSnmpdDebugDumpPdus       = 2
1102
begemotSnmpdDebugSyslogPri      = 7
1103
begemotSnmpdCommunityString.0.1 = $(read)
1104

    
1105
EOD;
1106

    
1107
/* No docs on what write strings do there for disable for now.
1108
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1109
		    $snmpdconf .= <<<EOD
1110
begemotSnmpdCommunityString.0.2 = $(write)
1111

    
1112
EOD;
1113
		}
1114
*/
1115

    
1116

    
1117
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1118
		    $snmpdconf .= <<<EOD
1119
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1120
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1121
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1122

    
1123
EOD;
1124
		}
1125

    
1126

    
1127
		$snmpdconf .= <<<EOD
1128
begemotSnmpdCommunityDisable    = 1
1129

    
1130
EOD;
1131

    
1132
		if(isset($config['snmpd']['bindlan'])) {
1133
			$bind_to_ip = get_interface_ip("lan");
1134
		} else {
1135
			$bind_to_ip = "0.0.0.0";
1136
		}
1137

    
1138
		if(is_port( $config['snmpd']['pollport'] )) {
1139
		    $snmpdconf .= <<<EOD
1140
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1141

    
1142
EOD;
1143

    
1144
		}
1145

    
1146
		$snmpdconf .= <<<EOD
1147
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1148
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1149

    
1150
# These are bsnmp macros not php vars.
1151
sysContact      = $(contact)
1152
sysLocation     = $(location)
1153
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1154

    
1155
snmpEnableAuthenTraps = 2
1156

    
1157
EOD;
1158

    
1159
		if (is_array( $config['snmpd']['modules'] )) {
1160
		    if(isset($config['snmpd']['modules']['mibii'])) {
1161
			$snmpdconf .= <<<EOD
1162
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1163

    
1164
EOD;
1165
		    }
1166

    
1167
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1168
			$snmpdconf .= <<<EOD
1169
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1170
%netgraph
1171
begemotNgControlNodeName = "snmpd"
1172

    
1173
EOD;
1174
		    }
1175

    
1176
		    if(isset($config['snmpd']['modules']['pf'])) {
1177
			$snmpdconf .= <<<EOD
1178
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1179

    
1180
EOD;
1181
		    }
1182

    
1183
		    if(isset($config['snmpd']['modules']['hostres'])) {
1184
			$snmpdconf .= <<<EOD
1185
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1186

    
1187
EOD;
1188
		    }
1189
		    if(isset($config['snmpd']['modules']['bridge'])) {
1190
			$snmpdconf .= <<<EOD
1191
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1192
# config must end with blank line
1193

    
1194

    
1195
EOD;
1196
		    }
1197
		}
1198

    
1199
		fwrite($fd, $snmpdconf);
1200
		fclose($fd);
1201

    
1202
		if (isset($config['snmpd']['bindlan'])) {
1203
			$bindlan = "";
1204
		}
1205

    
1206
		/* run bsnmpd */
1207
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1208
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1209

    
1210
		if ($g['booting'])
1211
			echo "done.\n";
1212
	}
1213

    
1214
	return 0;
1215
}
1216

    
1217
function services_dnsupdate_process($int = "") {
1218
	global $config, $g;
1219
	if(isset($config['system']['developerspew'])) {
1220
		$mt = microtime();
1221
		echo "services_dnsupdate_process() being called $mt\n";
1222
	}
1223

    
1224
	/* Dynamic DNS updating active? */
1225
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1226
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1227
			if (!isset($dnsupdate['enable']))
1228
				continue;
1229
			if (!empty($int) && $int != $dnsupdate['interface'])
1230
				continue;
1231

    
1232
			/* determine interface name */
1233
			$if = get_real_interface($dnsupdate['interface']);
1234
			$wanip = get_interface_ip($dnsupdate['interface']);
1235
			if ($wanip) {
1236

    
1237
				$keyname = $dnsupdate['keyname'];
1238
				/* trailing dot */
1239
				if (substr($keyname, -1) != ".")
1240
					$keyname .= ".";
1241

    
1242
				$hostname = $dnsupdate['host'];
1243
				/* trailing dot */
1244
				if (substr($hostname, -1) != ".")
1245
					$hostname .= ".";
1246

    
1247
				/* write private key file
1248
				   this is dumb - public and private keys are the same for HMAC-MD5,
1249
				   but nsupdate insists on having both */
1250
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1251
				$privkey .= <<<EOD
1252
Private-key-format: v1.2
1253
Algorithm: 157 (HMAC)
1254
Key: {$dnsupdate['keydata']}
1255

    
1256
EOD;
1257
				fwrite($fd, $privkey);
1258
				fclose($fd);
1259

    
1260
				/* write public key file */
1261
				if ($dnsupdate['keytype'] == "zone") {
1262
					$flags = 257;
1263
					$proto = 3;
1264
				} else if ($dnsupdate['keytype'] == "host") {
1265
					$flags = 513;
1266
					$proto = 3;
1267
				} else if ($dnsupdate['keytype'] == "user") {
1268
					$flags = 0;
1269
					$proto = 2;
1270
				}
1271

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

    
1276
				/* generate update instructions */
1277
				$upinst = "";
1278
				if (!empty($dnsupdate['server']))
1279
					$upinst .= "server {$dnsupdate['server']}\n";
1280
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1281
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1282
				$upinst .= "\n";	/* mind that trailing newline! */
1283

    
1284
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1285
				fwrite($fd, $upinst);
1286
				fclose($fd);
1287

    
1288
				/* invoke nsupdate */
1289
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1290
				if (isset($dnsupdate['usetcp']))
1291
					$cmd .= " -v";
1292
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1293
	
1294
				mwexec_bg($cmd);
1295
			}
1296
		}
1297
	}
1298

    
1299
	return 0;
1300
}
1301

    
1302
function setup_wireless_olsr() {
1303
	global $config, $g;
1304
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1305
		return;
1306
	if(isset($config['system']['developerspew'])) {
1307
		$mt = microtime();
1308
		echo "setup_wireless_olsr($interface) being called $mt\n";
1309
	}
1310
	conf_mount_rw();
1311
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1312
		$olsr_enable = $olsrd['enable'];
1313
		if($olsr_enable <> "on")
1314
			return;
1315
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1316

    
1317
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1318
			$enableannounce .= "\nHna4\n";
1319
			$enableannounce .= "{\n";
1320
		if($olsrd['announcedynamicroute'])
1321
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1322
		if($olsrd['enableannounce'] == "on")
1323
			$enableannounce .= "0.0.0.0 0.0.0.0";
1324
			$enableannounce .= "\n}\n";
1325
		} else {
1326
			$enableannounce = "";
1327
		}
1328

    
1329
		$olsr .= <<<EODA
1330
#
1331
# olsr.org OLSR daemon config file
1332
#
1333
# Lines starting with a # are discarded
1334
#
1335
# This file was generated by setup_wireless_olsr() in services.inc
1336
#
1337

    
1338
# This file is an example of a typical
1339
# configuration for a mostly static
1340
# network(regarding mobility) using
1341
# the LQ extention
1342

    
1343
# Debug level(0-9)
1344
# If set to 0 the daemon runs in the background
1345

    
1346
DebugLevel	2
1347

    
1348
# IP version to use (4 or 6)
1349

    
1350
IpVersion	4
1351

    
1352
# Clear the screen each time the internal state changes
1353

    
1354
ClearScreen     yes
1355

    
1356
{$enableannounce}
1357

    
1358
# Should olsrd keep on running even if there are
1359
# no interfaces available? This is a good idea
1360
# for a PCMCIA/USB hotswap environment.
1361
# "yes" OR "no"
1362

    
1363
AllowNoInt	yes
1364

    
1365
# TOS(type of service) value for
1366
# the IP header of control traffic.
1367
# If not set it will default to 16
1368

    
1369
#TosValue	16
1370

    
1371
# The fixed willingness to use(0-7)
1372
# If not set willingness will be calculated
1373
# dynamically based on battery/power status
1374
# if such information is available
1375

    
1376
#Willingness    	4
1377

    
1378
# Allow processes like the GUI front-end
1379
# to connect to the daemon.
1380

    
1381
IpcConnect
1382
{
1383
     # Determines how many simultaneously
1384
     # IPC connections that will be allowed
1385
     # Setting this to 0 disables IPC
1386

    
1387
     MaxConnections  0
1388

    
1389
     # By default only 127.0.0.1 is allowed
1390
     # to connect. Here allowed hosts can
1391
     # be added
1392

    
1393
     Host            127.0.0.1
1394
     #Host            10.0.0.5
1395

    
1396
     # You can also specify entire net-ranges
1397
     # that are allowed to connect. Multiple
1398
     # entries are allowed
1399

    
1400
     #Net             192.168.1.0 255.255.255.0
1401
}
1402

    
1403
# Wether to use hysteresis or not
1404
# Hysteresis adds more robustness to the
1405
# link sensing but delays neighbor registration.
1406
# Used by default. 'yes' or 'no'
1407

    
1408
UseHysteresis	no
1409

    
1410
# Hysteresis parameters
1411
# Do not alter these unless you know
1412
# what you are doing!
1413
# Set to auto by default. Allowed
1414
# values are floating point values
1415
# in the interval 0,1
1416
# THR_LOW must always be lower than
1417
# THR_HIGH.
1418

    
1419
#HystScaling	0.50
1420
#HystThrHigh	0.80
1421
#HystThrLow	0.30
1422

    
1423

    
1424
# Link quality level
1425
# 0 = do not use link quality
1426
# 1 = use link quality for MPR selection
1427
# 2 = use link quality for MPR selection and routing
1428
# Defaults to 0
1429

    
1430
LinkQualityLevel	{$olsrd['enablelqe']}
1431

    
1432
# Link quality window size
1433
# Defaults to 10
1434

    
1435
LinkQualityWinSize	10
1436

    
1437
# Polling rate in seconds(float).
1438
# Default value 0.05 sec
1439

    
1440
Pollrate	0.05
1441

    
1442

    
1443
# TC redundancy
1444
# Specifies how much neighbor info should
1445
# be sent in TC messages
1446
# Possible values are:
1447
# 0 - only send MPR selectors
1448
# 1 - send MPR selectors and MPRs
1449
# 2 - send all neighbors
1450
#
1451
# defaults to 0
1452

    
1453
TcRedundancy	2
1454

    
1455
#
1456
# MPR coverage
1457
# Specifies how many MPRs a node should
1458
# try select to reach every 2 hop neighbor
1459
#
1460
# Can be set to any integer >0
1461
#
1462
# defaults to 1
1463

    
1464
MprCoverage	3
1465

    
1466
# Example plugin entry with parameters:
1467

    
1468
EODA;
1469

    
1470
if($olsrd['enablehttpinfo'] == "on") {
1471
	$olsr .= <<<EODB
1472

    
1473
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1474
{
1475
    PlParam     "port"   "{$olsrd['port']}"
1476
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1477
}
1478

    
1479
EODB;
1480

    
1481
}
1482

    
1483
if($olsrd['enabledsecure'] == "on") {
1484
	$olsr .= <<<EODC
1485

    
1486
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1487
{
1488
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1489
}
1490

    
1491
EODC;
1492

    
1493
}
1494

    
1495
if($olsrd['enabledyngw'] == "on") {
1496

    
1497
	/* unset default route, olsr auto negotiates */
1498
	mwexec("/sbin/route delete default");
1499

    
1500
	$olsr .= <<<EODE
1501

    
1502
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1503
{
1504
    # how often to look for a inet gw, in seconds
1505
    # defaults to 5 secs, if commented out
1506
    PlParam     "Interval"   "{$olsrd['polling']}"
1507

    
1508
    # if one or more IPv4 addresses are given, do a ping on these in
1509
    # descending order to validate that there is not only an entry in
1510
    # routing table, but also a real internet connection. If any of
1511
    # these addresses could be pinged successfully, the test was
1512
    # succesful, i.e. if the ping on the 1st address was successful,the
1513
    # 2nd won't be pinged
1514
    PlParam     "Ping"       "{$olsrd['ping']}"
1515
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1516
}
1517

    
1518
EODE;
1519

    
1520
}
1521

    
1522
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1523
	$interfaces = explode(',', $conf['iface_array']);
1524
	foreach($interfaces as $interface) {
1525
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1526
$olsr .= <<<EODAD
1527
Interface "{$realinterface}"
1528
{
1529

    
1530
    # Hello interval in seconds(float)
1531
    HelloInterval    2.0
1532

    
1533
    # HELLO validity time
1534
    HelloValidityTime	20.0
1535

    
1536
    # TC interval in seconds(float)
1537
    TcInterval        5.0
1538

    
1539
    # TC validity time
1540
    TcValidityTime	30.0
1541

    
1542
    # MID interval in seconds(float)
1543
    MidInterval	5.0
1544

    
1545
    # MID validity time
1546
    MidValidityTime	30.0
1547

    
1548
    # HNA interval in seconds(float)
1549
    HnaInterval	5.0
1550

    
1551
    # HNA validity time
1552
    HnaValidityTime 	30.0
1553

    
1554
    # When multiple links exist between hosts
1555
    # the weight of interface is used to determine
1556
    # the link to use. Normally the weight is
1557
    # automatically calculated by olsrd based
1558
    # on the characteristics of the interface,
1559
    # but here you can specify a fixed value.
1560
    # Olsrd will choose links with the lowest value.
1561

    
1562
    # Weight 0
1563

    
1564

    
1565
}
1566

    
1567
EODAD;
1568

    
1569
	}
1570
	break;
1571
}
1572
		fwrite($fd, $olsr);
1573
		fclose($fd);
1574
	}
1575

    
1576
	if(is_process_running("olsrd"))
1577
		mwexec("/usr/bin/killall olsrd", true);
1578

    
1579
	sleep(2);
1580

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

    
1583
	conf_mount_ro();
1584
}
1585

    
1586
/* configure cron service */
1587
function configure_cron() {
1588
	global $g, $config;
1589
	conf_mount_rw();
1590
	/* preserve existing crontab entries */
1591
	$crontab_contents = file_get_contents("/etc/crontab");
1592
	$crontab_contents_a = split("\n", $crontab_contents);
1593
	
1594
	for ($i = 0; $i < count($crontab_contents_a); $i++) {
1595
		$item =& $crontab_contents_a[$i];
1596
		if (strpos($item, "# pfSense specific crontab entries") !== false) {
1597
			array_splice($crontab_contents_a, $i - 1);
1598
			break;
1599
		}
1600
	}
1601
	$crontab_contents = implode("\n", $crontab_contents_a) . "\n";
1602
	
1603
	
1604
	if (is_array($config['cron']['item'])) {
1605
		$crontab_contents .= "#\n";
1606
		$crontab_contents .= "# pfSense specific crontab entries\n";
1607
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1608
		$crontab_contents .= "#\n";
1609

    
1610
		foreach ($config['cron']['item'] as $item) {
1611
			$crontab_contents .= "\n{$item['minute']}\t";
1612
			$crontab_contents .= "{$item['hour']}\t";
1613
			$crontab_contents .= "{$item['mday']}\t";
1614
			$crontab_contents .= "{$item['month']}\t";
1615
			$crontab_contents .= "{$item['wday']}\t";
1616
			$crontab_contents .= "{$item['who']}\t";
1617
			$crontab_contents .= "{$item['command']}";
1618
		}
1619
    
1620
		$crontab_contents .= "\n#\n";
1621
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1622
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1623
		$crontab_contents .= "#\n\n";
1624
	}
1625
	
1626
	/* please maintain the newline at the end of file */
1627
	file_put_contents("/etc/crontab", $crontab_contents);
1628

    
1629
	/* do a HUP kill to force sync changes */
1630
	exec('/bin/pkill -HUP cron');
1631

    
1632
	conf_mount_ro();
1633
}
1634

    
1635
function upnp_action ($action) {
1636
	switch($action) {
1637
		case "start":
1638
			if(file_exists('/var/etc/miniupnpd.conf'))
1639
				mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf');
1640
			break;
1641
		case "stop":
1642
			while((int)exec("pgrep miniupnpd | wc -l") > 0)
1643
				mwexec('killall miniupnpd 2>/dev/null', true);
1644
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1645
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1646
			break;
1647
		case "restart":
1648
			upnp_action('stop');
1649
			upnp_action('start');
1650
			break;
1651
	}
1652
}
1653

    
1654
function upnp_start() {
1655
	global $config, $g;
1656

    
1657
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1658
		return;
1659

    
1660
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1661
		if($g['booting']) {
1662
			echo "Starting UPnP service... ";
1663
			require_once('/usr/local/pkg/miniupnpd.inc');
1664
			sync_package_miniupnpd();
1665
			echo "done.\n";
1666
		}
1667
		else {
1668
			upnp_action('start');
1669
		}
1670
	}
1671
}
1672

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

    
1676
	$is_installed = false;
1677

    
1678
	if(!$config['cron']['item'])
1679
		return;
1680

    
1681
	$x=0;
1682
	foreach($config['cron']['item'] as $item) {
1683
		if(strstr($item['command'], $command)) {
1684
			$is_installed = true;
1685
			break;
1686
		}
1687
		$x++;
1688
	}
1689

    
1690
	if($active) {
1691
		$cron_item = array();
1692
		$cron_item['minute'] = $minute;
1693
		$cron_item['hour'] = $hour;
1694
		$cron_item['mday'] = $monthday;
1695
		$cron_item['month'] = $month;
1696
		$cron_item['wday'] = $weekday;
1697
		$cron_item['who'] = $who;
1698
		$cron_item['command'] = $command;
1699
		if(!$is_installed) {
1700
			$config['cron']['item'][] = $cron_item;
1701
			write_config("Installed cron job for {$command}");
1702
		} else {
1703
			$config['cron']['item'][$x] = $cron_item;
1704
			write_config("Updated cron job for {$command}");
1705
		}
1706
	} else {
1707
		if(($is_installed == true) && ($x > 0)) {
1708
			unset($config['cron']['item'][$x]);
1709
			write_config("Remvoed cron job for {$command}");
1710
		}
1711
	}
1712
	configure_cron();
1713
}
1714

    
1715
?>
(37-37/54)