Project

General

Profile

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

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

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

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

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

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

    
34
/*
35
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/bin/sh	/usr/local/sbin/dhcpd	/usr/local/sbin/igmpproxy
36
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/usr/sbin/arp	/sbin/ifconfig	/usr/local/sbin/dnsmasq
37
	pfSense_BUILDER_BINARIES:	/usr/sbin/bsnmpd	/sbin/route	/usr/local/sbin/olsrd
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/miniupnpd	
39
	pfSense_MODULE:	utils
40
*/
41

    
42
function services_dhcpd_configure() {
43
	global $config, $g;
44
	
45
	if($g['services_dhcp_server_enable'] == false) 
46
		return;
47

    
48
	if(isset($config['system']['developerspew'])) {
49
		$mt = microtime();
50
		echo "services_dhcpd_configure($if) being called $mt\n";
51
	}
52
	
53
	/* kill any running dhcpd */
54
	if(is_process_running("dhcpd")) {
55
		mwexec("killall dhcpd", true);
56
		mwexec("killall -9 rtadvd", true);
57
	}
58

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

    
63
	/* if OLSRD is enabled, allow WAN to house DHCP. */
64
	if($config['installedpackages']['olsrd'])
65
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
66
				if($olsrd['enable'])
67
					$is_olsr_enabled = true;
68

    
69
	/* configure DHCPD chroot */
70
	$fd = fopen("{$g['tmp_path']}/dhcpd.sh","w");
71
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
72
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
73
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
74
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
75
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
76
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
77
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/run\n");	
78
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
79
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
80
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
81
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
82
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
83
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
84
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
85
	if(!trim($status))
86
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
87
	fclose($fd);
88
	mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh");
89

    
90
	if ($g['booting']) {
91
		if ($g['platform'] != "pfSense") {
92
			/* restore the leases, if we have them */
93
			if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) {
94
				$dhcprestore = "";
95
				$dhcpreturn = "";
96
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn);
97
				$dhcprestore = implode(" ", $dhcprestore);
98
				if($dhcpreturn <> 0) {
99
					log_error("DHCP leases restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
100
				}
101
			}
102
			if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) {
103
				$dhcprestore = "";
104
				$dhcpreturn = "";
105
				exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn);
106
				$dhcprestore = implode(" ", $dhcprestore);
107
				if($dhcpreturn <> 0) {
108
					log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n");
109
				}
110
			}
111
		}
112
	}
113

    
114
	$syscfg = $config['system'];
115
	$dhcpdcfg = $config['dhcpd'];
116
	$dhcpdv6cfg = $config['dhcpdv6'];
117
	$Iflist = get_configured_interface_list();
118
		
119
	if ($g['booting'])
120
		echo "Starting DHCP service...";
121
	else
122
		sleep(1);
123

    
124
	/* write dhcpd.conf */
125
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
126
	$fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w");
127
	if ((!$fd) || (! $fdv6)) {
128
		printf("Error: cannot open dhcpd.conf or dhcpdv6.conf in services_dhcpd_configure().\n");
129
		return 1;
130
	}
131

    
132
	$custoptions = "";
133
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {	
134
		if(is_array($dhcpifconf['numberoptions']) && is_array($dhcpifconf['numberoptions']['item'])) {
135
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
136
				$custoptions .= "option custom-{$dhcpif}-{$itemidx} code {$item['number']} = text;\n";
137
			}
138
		}
139
	}
140
	$custoptionsv6 = "";
141
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {	
142
		if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) {
143
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
144
				$custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n";
145
			}
146
		}
147
	}
148

    
149
	$dhcpdconf = <<<EOD
150
	
151
option domain-name "{$syscfg['domain']}";
152
option ldap-server code 95 = text;
153
option domain-search-list code 119 = text;
154
{$custoptions}
155
default-lease-time 7200;
156
max-lease-time 86400;
157
log-facility local7;
158
ddns-update-style none;
159
one-lease-per-client true;
160
deny duplicates;
161
ping-check true;
162

    
163
EOD;
164

    
165
	$dhcpdv6conf = <<<EOD
166
	
167
option domain-name "{$syscfg['domain']}";
168
option ldap-server code 95 = text;
169
option domain-search-list code 119 = text;
170
{$custoptions}
171
default-lease-time 7200;
172
max-lease-time 86400;
173
log-facility local7;
174
ddns-update-style none;
175
one-lease-per-client true;
176
deny duplicates;
177
ping-check true;
178

    
179
EOD;
180

    
181
	if(!isset($dhcpifconf['disableauthoritative']))
182
		$dhcpdconf .= "authoritative;\n";
183
	if(!isset($dhcpv6ifconf['disableauthoritative']))
184
		$dhcpdv6conf .= "authoritative;\n";
185

    
186
	if(isset($dhcpifconf['alwaysbroadcast'])) 
187
		$dhcpdconf .= "always-broadcast on\n";
188
	if(isset($dhcpv6ifconf['alwaysbroadcast'])) 
189
		$dhcpdv6conf .= "always-broadcast on\n";
190

    
191
	$dhcpdifs = array();
192
	$dhcpdv6ifs = array();
193

    
194
	/*    loop through and determine if we need to setup
195
	 *    failover peer "bleh" entries
196
	 */
197
	$dhcpnum = 0;
198
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
199

    
200
		interfaces_staticarp_configure($dhcpif);
201

    
202
		if (!isset($dhcpifconf['enable']))
203
			continue;
204

    
205
		if($dhcpifconf['failover_peerip'] <> "") {
206
			$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
207
			$intip = find_interface_ip($int);
208
			$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
209
			/*
210
			 *    yep, failover peer is defined.
211
			 *    does it match up to a defined vip?
212
			 */
213
			$skew = 110;
214
			$a_vip = &$config['virtualip']['vip'];
215
			if(is_array($a_vip)) {
216
				foreach ($a_vip as $vipent) {
217
					if($int == $real_dhcpif) {
218
						/* this is the interface! */
219
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
220
							$skew = 0;
221
					}
222
				}
223
			} else {
224
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
225
			}
226
			if($skew > 10) {
227
				$type = "secondary";
228
				$dhcpdconf_pri  = "mclt 600;\n";
229
				$my_port = "520";
230
				$peer_port = "519";
231
			} else {
232
				$my_port = "519";
233
				$peer_port = "520";
234
				$type = "primary";
235
				$dhcpdconf_pri  = "split 128;\n";
236
				$dhcpdconf_pri .= "  mclt 600;\n";
237
			}
238
			$dhcpdconf .= <<<EOPP
239
failover peer "dhcp{$dhcpnum}" {
240
  {$type};
241
  address {$intip};
242
  port {$my_port};
243
  peer address {$dhcpifconf['failover_peerip']};
244
  peer port {$peer_port};
245
  max-response-delay 10;
246
  max-unacked-updates 10;
247
  {$dhcpdconf_pri}
248
  load balance max seconds 3;
249
}
250

    
251
EOPP;
252
		$dhcpnum++;
253
		}
254
	}
255
	$dhcpv6num = 0;
256
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
257

    
258
		interfaces_staticarp_configure($dhcpv6if);
259

    
260
		if (!isset($dhcpv6ifconf['enable']))
261
			continue;
262

    
263
		if($dhcpv6ifconf['failover_peerip'] <> "") {
264
			$intv6 = guess_interface_from_ipv6($dhcpv6ifconf['failover_peerip']);
265
			$intipv6 = find_interface_ipv6($intv6);
266
			$real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if);
267
			/*
268
			 *    yep, failover peer is defined.
269
			 *    does it match up to a defined vip?
270
			 */
271
			$skew = 110;
272
			$a_vip = &$config['virtualip']['vip'];
273
			if(is_array($a_vip)) {
274
				foreach ($a_vip as $vipent) {
275
					if($intv6 == $real_dhcpv6if) {
276
						/* this is the interface! */
277
						if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20"))
278
							$skew = 0;
279
					}
280
				}
281
			} else {
282
				log_error("Warning!  DHCPv6 Failover setup and no CARP virtual IPv6's defined!");
283
			}
284
			if($skew > 10) {
285
				$typev6 = "secondary";
286
				$dhcpdv6conf_pri  = "mclt 600;\n";
287
				$my_portv6 = "520";
288
				$peer_portv6 = "519";
289
			} else {
290
				$my_portv6 = "519";
291
				$peer_portv6 = "520";
292
				$typev6 = "primary";
293
				$dhcpdv6conf_pri  = "split 128;\n";
294
				$dhcpdv6conf_pri .= "  mclt 600;\n";
295
			}
296
			$dhcpdv6conf .= <<<EOPP
297
failover peer "dhcpv6{$dhcpv6num}" {
298
  {$typev6};
299
  address {$intipv6};
300
  port {$my_portv6};
301
  peer address {$dhcpv6ifconf['failover_peerip']};
302
  peer port {$peer_portv6};
303
  max-response-delay 10;
304
  max-unacked-updates 10;
305
  {$dhcpdv6conf_pri}
306
  load balance max seconds 3;
307
}
308

    
309
EOPP;
310
		$dhcpv6num++;
311
		}
312
	}
313

    
314
	$dhcpnum = 0;
315

    
316
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
317

    
318
		$ifcfg = $config['interfaces'][$dhcpif];
319

    
320
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
321
			continue;
322
		$ifcfgip = get_interface_ip($dhcpif);
323
		$ifcfgsn = get_interface_subnet($dhcpif);
324
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
325
		$subnetmask = gen_subnet_mask($ifcfgsn);
326

    
327
		if($is_olsr_enabled == true)
328
			if($dhcpifconf['netmask'])
329
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
330

    
331
		$dnscfg = "";
332

    
333
		if ($dhcpifconf['domain']) {
334
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
335
		}
336
		
337
    		if($dhcpifconf['domainsearchlist'] <> "") {
338
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
339
    		}
340

    
341
		if (isset($dhcpifconf['ddnsupdate'])) {
342
			if($dhcpifconf['ddnsdomain'] <> "") {
343
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
344
			}
345
			$dnscfg .= "	ddns-update-style interim;\n";
346
		}
347

    
348
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
349
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
350
		} else if (isset($config['dnsmasq']['enable'])) {
351
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
352
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
353
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
354
		}
355

    
356
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
357
		$dhcpdconf .= "	pool {\n";
358

    
359
		/* is failover dns setup? */
360
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
361
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
362
			if($dhcpifconf['dnsserver'][1] <> "")
363
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
364
			$dhcpdconf .= ";\n";
365
		}
366

    
367
		if($dhcpifconf['failover_peerip'] <> "")
368
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
369

    
370
		if (isset($dhcpifconf['denyunknown']))
371
		   $dhcpdconf .= "		deny unknown clients;\n";
372

    
373
		if ($dhcpifconf['gateway'])
374
			$routers = $dhcpifconf['gateway'];
375
		else
376
			$routers = $ifcfgip;
377

    
378
		if($dhcpifconf['failover_peerip'] <> "") {
379
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
380
			$dhcpnum++;
381
		}
382

    
383
		$dhcpdconf .= <<<EOD
384
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
385
	}
386
	option routers {$routers};
387
$dnscfg
388

    
389
EOD;
390
    		// default-lease-time
391
		if ($dhcpifconf['defaultleasetime'])
392
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
393

    
394
		// max-lease-time
395
		if ($dhcpifconf['maxleasetime'])
396
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
397

    
398
		// netbios-name*
399
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
400
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
401
			$dhcpdconf .= "	option netbios-node-type 8;\n";
402
		}
403

    
404
		// ntp-servers
405
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
406
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
407

    
408
		// tftp-server-name
409
		if ($dhcpifconf['tftp'] <> "")
410
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
411

    
412
		// Handle option, number rowhelper values
413
		$dhcpdconf .= "\n";
414
		if($dhcpifconf['numberoptions']['item']) {
415
			foreach($dhcpifconf['numberoptions']['item'] as $itemidx => $item) {
416
				$dhcpdconf .= "	option custom-{$dhcpif}-{$itemidx} \"{$item['value']}\";\n";
417
			}
418
		}
419

    
420
		// ldap-server
421
		if ($dhcpifconf['ldap'] <> "")
422
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
423

    
424
		// net boot information
425
		if(isset($dhcpifconf['netboot'])) {
426
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
427
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
428
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
429
			}
430
			if ($dhcpifconf['rootpath'] <> "") {
431
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
432
      		}
433
		}
434
		
435
		$dhcpdconf .= <<<EOD
436
}
437

    
438
EOD;
439

    
440
		/* add static mappings */
441
		if (is_array($dhcpifconf['staticmap'])) {
442

    
443
			$i = 0;
444
			foreach ($dhcpifconf['staticmap'] as $sm) {
445
				$dhcpdconf .= <<<EOD
446
host s_{$dhcpif}_{$i} {
447
	hardware ethernet {$sm['mac']};
448

    
449
EOD;
450
				if ($sm['ipaddr'])
451
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
452

    
453
				if ($sm['hostname']) {
454
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
455
					$dhhostname = str_replace(".", "_", $dhhostname);
456
					$dhcpdconf .= "	option host-name {$dhhostname};\n";
457
				}
458
				if ($sm['netbootfile'])
459
					$dhcpdconf .= "	filename \"{$sm['netbootfile']}\";\n";
460

    
461
				$dhcpdconf .= "}\n";
462
				$i++;
463
			}
464
		}
465

    
466
		$dhcpdifs[] = get_real_interface($dhcpif);
467
	}
468

    
469
	$dhcpv6num = 0;
470
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
471

    
472
		$ifcfgv6 = $config['interfaces'][$dhcpv6if];
473

    
474
		if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if]))
475
			continue;
476
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
477
		$ifcfgsnv6 = get_interface_subnetv6($dhcpv6if);
478
		$subnetv6 = gen_subnetv6($ifcfgip, $ifcfgsn);
479
		$subnetmaskv6 = gen_subnet_mask($ifcfgsn);
480

    
481
		if($is_olsr_enabled == true)
482
			if($dhcpv6ifconf['netmask'])
483
				$subnetmask = gen_subnet_mask($dhcpv6ifconf['netmask']);
484

    
485
		$dnscfgv6 = "";
486

    
487
		if ($dhcpv6ifconf['domain']) {
488
			$dnscfgv6 .= "	dhcp6.option domain-name \"{$dhcpv6ifconf['domain']}\";\n";
489
		}
490
		
491
    		if($dhcpv6ifconf['domainsearchlist'] <> "") {
492
			$dnscfgv6 .= "	option dhcp6.domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
493
    		}
494

    
495
		if (isset($dhcpv6ifconf['ddnsupdate'])) {
496
			if($dhcpv6ifconf['ddnsdomain'] <> "") {
497
				$dnscfgv6 .= "	dhcp6.ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n";
498
			}
499
			$dnscfgv6 .= "	dhcp6.ddns-update-style interim;\n";
500
		}
501

    
502
		if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) {
503
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";";
504
		} else if (isset($config['dnsmasq']['enable'])) {
505
			$dnscfgv6 .= "	option dhcp6.name-servers {$ifcfgipv6};";
506
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
507
			$dnscfgv6 .= "	option dhcp6.name-servers " . join(",", $syscfg['dnsserver']) . ";";
508
		}
509

    
510
		$subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6));
511
		$dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n";
512

    
513
		/* is failover dns setup? */
514
		if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") {
515
			$dhcpdv6conf .= "		option domain-name-servers {$dhcpv6ifconf['dnsserver'][0]}";
516
			if($dhcpv6ifconf['dnsserver'][1] <> "")
517
				$dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}";
518
			$dhcpdv6conf .= ";\n";
519
		}
520

    
521
		if($dhcpv6ifconf['failover_peerip'] <> "")
522
			$dhcpdv6conf .= "		deny dynamic bootp clients;\n";
523

    
524
		if (isset($dhcpv6ifconf['denyunknown']))
525
		   $dhcpdv6conf .= "		deny unknown clients;\n";
526

    
527
		if ($dhcpv6ifconf['gateway'])
528
			$routersv6 = $dhcpv6ifconf['gateway'];
529
		else
530
			$routersv6 = $ifcfgipv6;
531

    
532
		if($dhcpv6ifconf['failover_peerip'] <> "") {
533
			$dhcpdv6conf .= "		failover peer \"dhcpv6{$dhcpv6num}\";\n";
534
			$dhcpv6num++;
535
		}
536

    
537
		$dhcpdv6conf .= <<<EOD
538
	range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
539
	# Not supported in IPv6; option dhcp6.routers {$routersv6};
540
$dnscfgv6
541

    
542
EOD;
543
    		// default-lease-time
544
		if ($dhcpv6ifconf['defaultleasetime'])
545
			$dhcpdv6conf .= "	default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n";
546

    
547
		// max-lease-time
548
		if ($dhcpv6ifconf['maxleasetime'])
549
			$dhcpdv6conf .= "	max-lease-time {$dhcpv6ifconf['maxleasetime']};\n";
550

    
551
		// netbios-name*
552
		if (is_array($dhcpv6ifconf['winsserver']) && $dhcpv6ifconf['winsserver'][0]) {
553
			$dhcpdv6conf .= "	option netbios-name-servers " . join(",", $dhcpv6ifconf['winsserver']) . ";\n";
554
			$dhcpdv6conf .= "	option netbios-node-type 8;\n";
555
		}
556

    
557
		// ntp-servers
558
		if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0])
559
			$dhcpdv6conf .= "	option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
560

    
561
		// tftp-server-name
562
		if ($dhcpv6ifconf['tftp'] <> "")
563
			$dhcpdv6conf .= "	option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n";
564

    
565
		// Handle option, number rowhelper values
566
		$dhcpdv6conf .= "\n";
567
		if($dhcpv6ifconf['numberoptions']['item']) {
568
			foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) {
569
				$dhcpdv6conf .= "	option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n";
570
			}
571
		}
572

    
573
		// ldap-server
574
		if ($dhcpv6ifconf['ldap'] <> "")
575
			$dhcpdv6conf .= "	option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
576

    
577
		// net boot information
578
		if(isset($dhcpv6ifconf['netboot'])) {
579
			if (($dhcpv6ifconf['next-server'] <> "") && ($dhcpv6ifconf['filename'] <> "")) {
580
				$dhcpdv6conf .= "	next-server {$dhcpv6ifconf['next-server']};\n";
581
				$dhcpdv6conf .= "	filename \"{$dhcpv6ifconf['filename']}\";\n";
582
			}
583
			if ($dhcpv6ifconf['rootpath'] <> "") {
584
				$dhcpdv6conf .= "	option root-path \"{$dhcpv6ifconf['rootpath']}\";\n";
585
      		}
586
	}
587
		
588
		$dhcpdv6conf .= <<<EOD
589
}
590
EOD;
591

    
592
		/* add static mappings */
593
		if (is_array($dhcpv6ifconf['staticmap'])) {
594

    
595
			$i = 0;
596
			foreach ($dhcpv6ifconf['staticmap'] as $sm) {
597
				$dhcpdv6conf .= <<<EOD
598
host s_{$dhcpv6if}_{$i} {
599
	hardware ethernet {$sm['mac']};
600

    
601
EOD;
602
				if ($sm['ipaddr'])
603
					$dhcpdv6conf .= "	fixed-address6 {$sm['ipaddr']};\n";
604

    
605
				if ($sm['hostname']) {
606
					$dhhostname = str_replace(" ", "_", $sm['hostname']);
607
					$dhhostname = str_replace(".", "_", $dhhostname);
608
					$dhcpdv6conf .= "	option host-name {$dhhostname};\n";
609
				}
610
				if ($sm['netbootfile'])
611
					$dhcpdv6conf .= "	filename \"{$sm['netbootfile']}\";\n";
612

    
613
				$dhcpdv6conf .= "}\n";
614
				$i++;
615
			}
616
		}
617

    
618
		$dhcpdv6ifs[] = get_real_interface($dhcpv6if);
619
	}
620

    
621
	fwrite($fd, $dhcpdconf);
622
	fclose($fd);
623
	fwrite($fdv6, $dhcpdv6conf);
624
	fclose($fdv6);
625

    
626
	/* create an empty leases database */
627
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
628
	touch("{$g['varrun_path']}/dhcpd.pid");
629
	/* create an empty leases v6 database */
630
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases");
631
	touch("{$g['varrun_path']}/dhcpdv6.pid");
632
	
633

    
634
	/* fire up dhcpd in a chroot */
635
	if(count($dhcpdifs) > 0) {
636
		mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf " .
637
			join(" ", $dhcpdifs));
638
	}
639

    
640
	if(count($dhcpdv6ifs) > 0) {
641
		mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf " .
642
			join(" ", $dhcpdv6ifs));
643
		mwexec("/usr/sbin/rtadvd " . join(" ", $dhcpdv6ifs));
644
	}
645
	if ($g['booting']) {
646
		print "done.\n";
647
	}
648

    
649
	return 0;
650
}
651

    
652
function services_igmpproxy_configure() {
653
        global $config, $g;
654

    
655
        $iflist = get_configured_interface_list();
656

    
657
        /* kill any running igmpproxy */
658
        killbyname("igmpproxy");
659

    
660
	if (!is_array($config['igmpproxy']['igmpentry']))
661
		return 1;
662

    
663
        $igmpconf = <<<EOD
664

    
665
##------------------------------------------------------
666
## Enable Quickleave mode (Sends Leave instantly)
667
##------------------------------------------------------
668
quickleave
669

    
670
EOD;
671

    
672
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
673
                unset($iflist[$igmpcf['ifname']]);
674
                $realif = get_real_interface($igmpcf['ifname']);
675
                if (empty($igmpcf['threshold']))
676
                        $threshld = 1;
677
                else
678
                        $threshld = $igmpcf['threshold'];
679
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
680

    
681
                if ($igmpcf['address'] <> "") {
682
                        $item = explode(" ", $igmpcf['address']);
683
                        foreach($item as $iww)
684
                                $igmpconf .= "altnet {$iww}\n";
685
                }
686
                $igmpconf .= "\n";
687
        }
688
        foreach ($iflist as $ifn) {
689
                $realif = get_real_interface($ifn);
690
                $igmpconf .= "phyint {$realif} disabled\n";
691
        }
692

    
693
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
694
        if (!$igmpfl) {
695
                log_error("Could not write Igmpproxy configuration file!");
696
                return;
697
        }
698
        fwrite($igmpfl, $igmpconf);
699
        fclose($igmpfl);
700

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

    
704
        return 0;
705
}
706

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

    
714
        $ifcfg = $config['interfaces'][$if];
715

    
716
	if (empty($if) || empty($ifcfg['if']))
717
		return 0;
718

    
719
        /* Enable staticarp, if enabled */
720
        if(isset($config['dhcpd'][$if]['staticarp'])) {
721
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
722
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
723
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
724

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

    
728
                        }
729

    
730
                }
731
        } else {
732
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
733
                mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
734
        }
735

    
736
        return 0;
737
}
738

    
739
function services_dhcrelay_configure() {
740
	global $config, $g;
741
	if(isset($config['system']['developerspew'])) {
742
		$mt = microtime();
743
		echo "services_dhcrelay_configure() being called $mt\n";
744
	}
745

    
746
	/* kill any running dhcrelay */
747
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
748

    
749
	$dhcrelaycfg =& $config['dhcrelay'];
750

    
751
	/* DHCPRelay enabled on any interfaces? */
752
	if (!isset($dhcrelaycfg['enable']))
753
		return 0;
754

    
755
	if ($g['booting'])
756
		echo "Starting DHCP relay service...";
757
	else
758
		sleep(1);
759

    
760
	$iflist = get_configured_interface_list();
761

    
762
	$dhcifaces = explode(",", $dhcrelaycfg['interface']);
763
	foreach ($dhcifaces as $dhcrelayif) {
764
		if (!isset($iflist[$dhcrelayif]) ||
765
			link_interface_to_bridge($dhcrelayif))
766
			continue;
767

    
768
		if (is_ipaddr(get_interface_ip($dhcrelayif)))
769
			$dhcrelayifs[] = get_real_interface($dhcrelayif);
770
	}
771

    
772
	/* 
773
	 * In order for the relay to work, it needs to be active
774
	 * on the interface in which the destination server sits.
775
	 */
776
	$srvips = explode(",", $dhcrelaycfg['server']);
777
	foreach ($srvips as $srcidx => $srvip) {
778
		unset($destif);
779
		foreach ($iflist as $ifname) {
780
			$subnet = get_interface_ip($ifname);
781
			if (!is_ipaddr($subnet))
782
				continue;
783
			$subnet .=  "/" . get_interface_subnet($ifname);
784
			if (ip_in_subnet($srvip, $subnet)) {
785
				$destif = get_real_interface($ifname);
786
				break;
787
			}
788
		}
789
		if (!isset($destif)) {
790
			if (is_array($config['staticroutes']['route'])) {
791
				foreach ($config['staticroutes']['route'] as $rtent) {
792
					if (ip_in_subnet($srvip, $rtent['network'])) {
793
						$a_gateways = return_gateways_array(true);
794
						$destif = $a_gateways[$rtent['gateway']]['interface'];
795
						break;
796
					}
797
				}
798
			}
799
		}
800

    
801
		if (!isset($destif)) {
802
			/* Create a array from the existing route table */
803
        		exec("/usr/bin/netstat -rnWf inet", $route_str);
804
        		array_shift($route_str);
805
        		array_shift($route_str);
806
        		array_shift($route_str);
807
        		array_shift($route_str);
808
        		$route_arr = array();
809
        		foreach($route_str as $routeline) {
810
                		$items = preg_split("/[ ]+/i", $routeline);
811
				if (ip_in_subnet($srvip, $items[0])) {
812
					$destif = trim($items[2]);
813
					break;
814
				}
815
        		}
816
		}
817
	
818
		if (!isset($destif)) {
819
			if (is_array($config['gateways']['gateway_item'])) {
820
				foreach ($config['gateways']['gateway_item'] as $gateway) {
821
					if (isset($gateway['defaultgw'])) {
822
						$a_gateways = return_gateways_array(true);
823
                                        	$destif = $a_gateways[$rtent['gateway']]['interface'];
824
						break;
825
					}		
826
				}
827
			} else
828
				$destif = get_real_interface("wan");
829
		}
830

    
831
		if (!empty($destif))
832
			$dhcrelayifs[] = $destif;
833
	}
834
	$dhcrelayifs = array_unique($dhcrelayifs);
835

    
836
	/* fire up dhcrelay */
837
	if (empty($dhcrelayifs)) {
838
		log_error("No suitable interface found for running dhcrelay!");
839
		return; /* XXX */
840
	}
841

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

    
844
	if (isset($dhcrelaycfg['agentoption']))
845
		$cmd .=  " -a -m replace";
846

    
847
	$cmd .= " " . implode(" ", $srvips);
848
	mwexec($cmd);
849

    
850
	return 0;
851
}
852

    
853
function services_dyndns_configure_client($conf) {
854

    
855
	if (!isset($conf['enable']))
856
		return;
857

    
858
	/* load up the dyndns.class */
859
	require_once("dyndns.class");
860

    
861
	log_error("DynDns: Running updatedns()");
862

    
863
	$dns = new updatedns($dnsService = $conf['type'],
864
		$dnsHost = $conf['host'],
865
		$dnsUser = $conf['username'],
866
		$dnsPass = $conf['password'],
867
		$dnsWilcard = $conf['wildcard'],
868
		$dnsMX = $conf['mx'], 
869
		$dnsIf = "{$conf['interface']}");
870

    
871
}
872

    
873
function services_dyndns_configure($int = "") {
874
	global $config, $g;
875
	if(isset($config['system']['developerspew'])) {
876
		$mt = microtime();
877
		echo "services_dyndns_configure() being called $mt\n";
878
	}
879

    
880
	$dyndnscfg = $config['dyndnses']['dyndns'];
881

    
882
	if (is_array($dyndnscfg)) {
883
		if ($g['booting']) 
884
			echo "Starting DynDNS clients...";
885

    
886
		foreach ($dyndnscfg as $dyndns) {
887
			if (!empty($int) && $int != $dyndns['interface'])
888
				continue;
889

    
890
			services_dyndns_configure_client($dyndns);
891

    
892
			sleep(1);
893
		}
894

    
895
		if ($g['booting'])
896
			echo "done.\n";
897
	}
898

    
899
	return 0;
900
}
901

    
902
function services_dnsmasq_configure() {
903
	global $config, $g;
904
	$return = 0;
905
	
906
	if(isset($config['system']['developerspew'])) {
907
		$mt = microtime();
908
		echo "services_dnsmasq_configure() being called $mt\n";
909
	}
910

    
911
	/* kill any running dnsmasq */
912
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
913

    
914
	if (isset($config['dnsmasq']['enable'])) {
915

    
916
		if ($g['booting'])
917
			echo "Starting DNS forwarder...";
918
		else
919
			sleep(1);
920

    
921
		/* generate hosts file */
922
		if(system_hosts_generate()!=0)
923
			$return = 1;
924

    
925
		$args = "";
926

    
927
		if (isset($config['dnsmasq']['regdhcp'])) {
928
			$args .= " --dhcp-hostsfile={$g['varetc_path']}/hosts ";
929
		}
930
		
931
		/* Setup forwarded domains */
932
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
933
			foreach($config['dnsmasq']['domainoverrides'] as $override) {
934
			        $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
935
			}
936
		}
937

    
938
		/* Allow DNS Rebind for forwarded domains */
939
		if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
940
			if(!isset($config['system']['webgui']['nodnsrebindcheck'])) {
941
				foreach($config['dnsmasq']['domainoverrides'] as $override) {
942
					$args .= ' --rebind-domain-ok=/' . $override['domain'] . '/ ';
943
				}
944
			}
945
		}
946

    
947
		if(!isset($config['system']['webgui']['nodnsrebindcheck']))
948
			$dns_rebind = "--rebind-localhost-ok --stop-dns-rebind";
949

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

    
953
		if ($g['booting'])
954
			echo "done.\n";
955
	}
956

    
957
	if (!$g['booting']) {
958
		if(services_dhcpd_configure()!=0)
959
			$return = 1;
960
	}
961

    
962
	return $return;
963
}
964

    
965
function services_snmpd_configure() {
966
	global $config, $g;
967
	if(isset($config['system']['developerspew'])) {
968
		$mt = microtime();
969
		echo "services_snmpd_configure() being called $mt\n";
970
	}
971

    
972
	/* kill any running snmpd */
973
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
974
	if(is_process_running("bsnmpd")) 
975
		mwexec("/usr/bin/killall bsnmpd", true);
976

    
977
	if (isset($config['snmpd']['enable'])) {
978

    
979
		if ($g['booting'])
980
			echo "Starting SNMP daemon... ";
981

    
982
		/* generate snmpd.conf */
983
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
984
		if (!$fd) {
985
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
986
			return 1;
987
		}
988

    
989

    
990
		$snmpdconf = <<<EOD
991
location := "{$config['snmpd']['syslocation']}"
992
contact := "{$config['snmpd']['syscontact']}"
993
read := "{$config['snmpd']['rocommunity']}"
994

    
995
EOD;
996

    
997
/* No docs on what write strings do there for disable for now.
998
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
999
		    $snmpdconf .= <<<EOD
1000
# write string
1001
write := "{$config['snmpd']['rwcommunity']}"
1002

    
1003
EOD;
1004
		}
1005
*/
1006

    
1007

    
1008
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1009
		    $snmpdconf .= <<<EOD
1010
# SNMP Trap support.
1011
traphost := {$config['snmpd']['trapserver']}
1012
trapport := {$config['snmpd']['trapserverport']}
1013
trap := "{$config['snmpd']['trapstring']}"
1014

    
1015

    
1016
EOD;
1017
		}
1018

    
1019

    
1020
		$snmpdconf .= <<<EOD
1021
system := 1     # pfSense
1022
%snmpd
1023
begemotSnmpdDebugDumpPdus       = 2
1024
begemotSnmpdDebugSyslogPri      = 7
1025
begemotSnmpdCommunityString.0.1 = $(read)
1026

    
1027
EOD;
1028

    
1029
/* No docs on what write strings do there for disable for now.
1030
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
1031
		    $snmpdconf .= <<<EOD
1032
begemotSnmpdCommunityString.0.2 = $(write)
1033

    
1034
EOD;
1035
		}
1036
*/
1037

    
1038

    
1039
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
1040
		    $snmpdconf .= <<<EOD
1041
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
1042
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
1043
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
1044

    
1045
EOD;
1046
		}
1047

    
1048

    
1049
		$snmpdconf .= <<<EOD
1050
begemotSnmpdCommunityDisable    = 1
1051

    
1052
EOD;
1053

    
1054
		if(isset($config['snmpd']['bindlan'])) {
1055
			$bind_to_ip = get_interface_ip("lan");
1056
		} else {
1057
			$bind_to_ip = "0.0.0.0";
1058
		}
1059

    
1060
		if(is_port( $config['snmpd']['pollport'] )) {
1061
		    $snmpdconf .= <<<EOD
1062
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
1063

    
1064
EOD;
1065

    
1066
		}
1067

    
1068
		$snmpdconf .= <<<EOD
1069
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
1070
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
1071

    
1072
# These are bsnmp macros not php vars.
1073
sysContact      = $(contact)
1074
sysLocation     = $(location)
1075
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
1076

    
1077
snmpEnableAuthenTraps = 2
1078

    
1079
EOD;
1080

    
1081
		if (is_array( $config['snmpd']['modules'] )) {
1082
		    if(isset($config['snmpd']['modules']['mibii'])) {
1083
			$snmpdconf .= <<<EOD
1084
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
1085

    
1086
EOD;
1087
		    }
1088

    
1089
		    if(isset($config['snmpd']['modules']['netgraph'])) {
1090
			$snmpdconf .= <<<EOD
1091
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
1092
%netgraph
1093
begemotNgControlNodeName = "snmpd"
1094

    
1095
EOD;
1096
		    }
1097

    
1098
		    if(isset($config['snmpd']['modules']['pf'])) {
1099
			$snmpdconf .= <<<EOD
1100
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
1101

    
1102
EOD;
1103
		    }
1104

    
1105
		    if(isset($config['snmpd']['modules']['hostres'])) {
1106
			$snmpdconf .= <<<EOD
1107
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
1108

    
1109
EOD;
1110
		    }
1111
		    if(isset($config['snmpd']['modules']['bridge'])) {
1112
			$snmpdconf .= <<<EOD
1113
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
1114
# config must end with blank line
1115

    
1116

    
1117
EOD;
1118
		    }
1119
		}
1120

    
1121
		fwrite($fd, $snmpdconf);
1122
		fclose($fd);
1123

    
1124
		if (isset($config['snmpd']['bindlan'])) {
1125
			$bindlan = "";
1126
		}
1127

    
1128
		/* run bsnmpd */
1129
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
1130
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
1131

    
1132
		if ($g['booting'])
1133
			echo "done.\n";
1134
	}
1135

    
1136
	return 0;
1137
}
1138

    
1139
function services_dnsupdate_process($int = "") {
1140
	global $config, $g;
1141
	if(isset($config['system']['developerspew'])) {
1142
		$mt = microtime();
1143
		echo "services_dnsupdate_process() being called $mt\n";
1144
	}
1145

    
1146
	/* Dynamic DNS updating active? */
1147
	if (is_array($config['dnsupdates']['dnsupdate'])) {
1148
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
1149
			if (!isset($dnsupdate['enable']))
1150
				continue;
1151
			if (!empty($int) && $int != $dnsupdate['interface'])
1152
				continue;
1153

    
1154
			/* determine interface name */
1155
			$if = get_real_interface($dnsupdate['interface']);
1156
			$wanip = get_interface_ip($dnsupdate['interface']);
1157
			if ($wanip) {
1158

    
1159
				$keyname = $dnsupdate['keyname'];
1160
				/* trailing dot */
1161
				if (substr($keyname, -1) != ".")
1162
					$keyname .= ".";
1163

    
1164
				$hostname = $dnsupdate['host'];
1165
				/* trailing dot */
1166
				if (substr($hostname, -1) != ".")
1167
					$hostname .= ".";
1168

    
1169
				/* write private key file
1170
				   this is dumb - public and private keys are the same for HMAC-MD5,
1171
				   but nsupdate insists on having both */
1172
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
1173
				$privkey .= <<<EOD
1174
Private-key-format: v1.2
1175
Algorithm: 157 (HMAC)
1176
Key: {$dnsupdate['keydata']}
1177

    
1178
EOD;
1179
				fwrite($fd, $privkey);
1180
				fclose($fd);
1181

    
1182
				/* write public key file */
1183
				if ($dnsupdate['keytype'] == "zone") {
1184
					$flags = 257;
1185
					$proto = 3;
1186
				} else if ($dnsupdate['keytype'] == "host") {
1187
					$flags = 513;
1188
					$proto = 3;
1189
				} else if ($dnsupdate['keytype'] == "user") {
1190
					$flags = 0;
1191
					$proto = 2;
1192
				}
1193

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

    
1198
				/* generate update instructions */
1199
				$upinst = "";
1200
				if (!empty($dnsupdate['server']))
1201
					$upinst .= "server {$dnsupdate['server']}\n";
1202
				$upinst .= "update delete {$dnsupdate['host']} A\n";
1203
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
1204
				$upinst .= "\n";	/* mind that trailing newline! */
1205

    
1206
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
1207
				fwrite($fd, $upinst);
1208
				fclose($fd);
1209

    
1210
				/* invoke nsupdate */
1211
				$cmd = "/usr/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
1212
				if (isset($dnsupdate['usetcp']))
1213
					$cmd .= " -v";
1214
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
1215
	
1216
				mwexec_bg($cmd);
1217
			}
1218
		}
1219
	}
1220

    
1221
	return 0;
1222
}
1223

    
1224
function setup_wireless_olsr() {
1225
	global $config, $g;
1226
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
1227
		return;
1228
	if(isset($config['system']['developerspew'])) {
1229
		$mt = microtime();
1230
		echo "setup_wireless_olsr($interface) being called $mt\n";
1231
	}
1232
	conf_mount_rw();
1233
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
1234
		$olsr_enable = $olsrd['enable'];
1235
		if($olsr_enable <> "on")
1236
			return;
1237
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
1238

    
1239
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
1240
			$enableannounce .= "\nHna4\n";
1241
			$enableannounce .= "{\n";
1242
		if($olsrd['announcedynamicroute'])
1243
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
1244
		if($olsrd['enableannounce'] == "on")
1245
			$enableannounce .= "0.0.0.0 0.0.0.0";
1246
			$enableannounce .= "\n}\n";
1247
		} else {
1248
			$enableannounce = "";
1249
		}
1250

    
1251
		$olsr .= <<<EODA
1252
#
1253
# olsr.org OLSR daemon config file
1254
#
1255
# Lines starting with a # are discarded
1256
#
1257
# This file was generated by setup_wireless_olsr() in services.inc
1258
#
1259

    
1260
# This file is an example of a typical
1261
# configuration for a mostly static
1262
# network(regarding mobility) using
1263
# the LQ extention
1264

    
1265
# Debug level(0-9)
1266
# If set to 0 the daemon runs in the background
1267

    
1268
DebugLevel	2
1269

    
1270
# IP version to use (4 or 6)
1271

    
1272
IpVersion	4
1273

    
1274
# Clear the screen each time the internal state changes
1275

    
1276
ClearScreen     yes
1277

    
1278
{$enableannounce}
1279

    
1280
# Should olsrd keep on running even if there are
1281
# no interfaces available? This is a good idea
1282
# for a PCMCIA/USB hotswap environment.
1283
# "yes" OR "no"
1284

    
1285
AllowNoInt	yes
1286

    
1287
# TOS(type of service) value for
1288
# the IP header of control traffic.
1289
# If not set it will default to 16
1290

    
1291
#TosValue	16
1292

    
1293
# The fixed willingness to use(0-7)
1294
# If not set willingness will be calculated
1295
# dynamically based on battery/power status
1296
# if such information is available
1297

    
1298
#Willingness    	4
1299

    
1300
# Allow processes like the GUI front-end
1301
# to connect to the daemon.
1302

    
1303
IpcConnect
1304
{
1305
     # Determines how many simultaneously
1306
     # IPC connections that will be allowed
1307
     # Setting this to 0 disables IPC
1308

    
1309
     MaxConnections  0
1310

    
1311
     # By default only 127.0.0.1 is allowed
1312
     # to connect. Here allowed hosts can
1313
     # be added
1314

    
1315
     Host            127.0.0.1
1316
     #Host            10.0.0.5
1317

    
1318
     # You can also specify entire net-ranges
1319
     # that are allowed to connect. Multiple
1320
     # entries are allowed
1321

    
1322
     #Net             192.168.1.0 255.255.255.0
1323
}
1324

    
1325
# Wether to use hysteresis or not
1326
# Hysteresis adds more robustness to the
1327
# link sensing but delays neighbor registration.
1328
# Used by default. 'yes' or 'no'
1329

    
1330
UseHysteresis	no
1331

    
1332
# Hysteresis parameters
1333
# Do not alter these unless you know
1334
# what you are doing!
1335
# Set to auto by default. Allowed
1336
# values are floating point values
1337
# in the interval 0,1
1338
# THR_LOW must always be lower than
1339
# THR_HIGH.
1340

    
1341
#HystScaling	0.50
1342
#HystThrHigh	0.80
1343
#HystThrLow	0.30
1344

    
1345

    
1346
# Link quality level
1347
# 0 = do not use link quality
1348
# 1 = use link quality for MPR selection
1349
# 2 = use link quality for MPR selection and routing
1350
# Defaults to 0
1351

    
1352
LinkQualityLevel	{$olsrd['enablelqe']}
1353

    
1354
# Link quality window size
1355
# Defaults to 10
1356

    
1357
LinkQualityWinSize	10
1358

    
1359
# Polling rate in seconds(float).
1360
# Default value 0.05 sec
1361

    
1362
Pollrate	0.05
1363

    
1364

    
1365
# TC redundancy
1366
# Specifies how much neighbor info should
1367
# be sent in TC messages
1368
# Possible values are:
1369
# 0 - only send MPR selectors
1370
# 1 - send MPR selectors and MPRs
1371
# 2 - send all neighbors
1372
#
1373
# defaults to 0
1374

    
1375
TcRedundancy	2
1376

    
1377
#
1378
# MPR coverage
1379
# Specifies how many MPRs a node should
1380
# try select to reach every 2 hop neighbor
1381
#
1382
# Can be set to any integer >0
1383
#
1384
# defaults to 1
1385

    
1386
MprCoverage	3
1387

    
1388
# Example plugin entry with parameters:
1389

    
1390
EODA;
1391

    
1392
if($olsrd['enablehttpinfo'] == "on") {
1393
	$olsr .= <<<EODB
1394

    
1395
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1396
{
1397
    PlParam     "port"   "{$olsrd['port']}"
1398
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1399
}
1400

    
1401
EODB;
1402

    
1403
}
1404

    
1405
if($olsrd['enabledsecure'] == "on") {
1406
	$olsr .= <<<EODC
1407

    
1408
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1409
{
1410
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1411
}
1412

    
1413
EODC;
1414

    
1415
}
1416

    
1417
if($olsrd['enabledyngw'] == "on") {
1418

    
1419
	/* unset default route, olsr auto negotiates */
1420
	mwexec("/sbin/route delete default");
1421

    
1422
	$olsr .= <<<EODE
1423

    
1424
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1425
{
1426
    # how often to look for a inet gw, in seconds
1427
    # defaults to 5 secs, if commented out
1428
    PlParam     "Interval"   "{$olsrd['polling']}"
1429

    
1430
    # if one or more IPv4 addresses are given, do a ping on these in
1431
    # descending order to validate that there is not only an entry in
1432
    # routing table, but also a real internet connection. If any of
1433
    # these addresses could be pinged successfully, the test was
1434
    # succesful, i.e. if the ping on the 1st address was successful,the
1435
    # 2nd won't be pinged
1436
    PlParam     "Ping"       "{$olsrd['ping']}"
1437
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1438
}
1439

    
1440
EODE;
1441

    
1442
}
1443

    
1444
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1445
	$interfaces = explode(',', $conf['iface_array']);
1446
	foreach($interfaces as $interface) {
1447
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1448
$olsr .= <<<EODAD
1449
Interface "{$realinterface}"
1450
{
1451

    
1452
    # Hello interval in seconds(float)
1453
    HelloInterval    2.0
1454

    
1455
    # HELLO validity time
1456
    HelloValidityTime	20.0
1457

    
1458
    # TC interval in seconds(float)
1459
    TcInterval        5.0
1460

    
1461
    # TC validity time
1462
    TcValidityTime	30.0
1463

    
1464
    # MID interval in seconds(float)
1465
    MidInterval	5.0
1466

    
1467
    # MID validity time
1468
    MidValidityTime	30.0
1469

    
1470
    # HNA interval in seconds(float)
1471
    HnaInterval	5.0
1472

    
1473
    # HNA validity time
1474
    HnaValidityTime 	30.0
1475

    
1476
    # When multiple links exist between hosts
1477
    # the weight of interface is used to determine
1478
    # the link to use. Normally the weight is
1479
    # automatically calculated by olsrd based
1480
    # on the characteristics of the interface,
1481
    # but here you can specify a fixed value.
1482
    # Olsrd will choose links with the lowest value.
1483

    
1484
    # Weight 0
1485

    
1486

    
1487
}
1488

    
1489
EODAD;
1490

    
1491
	}
1492
	break;
1493
}
1494
		fwrite($fd, $olsr);
1495
		fclose($fd);
1496
	}
1497

    
1498
	if(is_process_running("olsrd"))
1499
		mwexec("/usr/bin/killall olsrd", true);
1500

    
1501
	sleep(2);
1502

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

    
1505
	conf_mount_ro();
1506
}
1507

    
1508
/* configure cron service */
1509
function configure_cron() {
1510
	global $g, $config;
1511
	conf_mount_rw();
1512
	/* preserve existing crontab entries */
1513
	$crontab_contents = file_get_contents("/etc/crontab");
1514
	$crontab_contents_a = split("\n", $crontab_contents);
1515
	
1516
	for ($i = 0; $i < count($crontab_contents_a); $i++) {
1517
		$item =& $crontab_contents_a[$i];
1518
		if (strpos($item, "# pfSense specific crontab entries") !== false) {
1519
			array_splice($crontab_contents_a, $i - 1);
1520
			break;
1521
		}
1522
	}
1523
	$crontab_contents = implode("\n", $crontab_contents_a) . "\n";
1524
	
1525
	
1526
	if (is_array($config['cron']['item'])) {
1527
		$crontab_contents .= "#\n";
1528
		$crontab_contents .= "# pfSense specific crontab entries\n";
1529
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1530
		$crontab_contents .= "#\n";
1531

    
1532
		foreach ($config['cron']['item'] as $item) {
1533
			$crontab_contents .= "\n{$item['minute']}\t";
1534
			$crontab_contents .= "{$item['hour']}\t";
1535
			$crontab_contents .= "{$item['mday']}\t";
1536
			$crontab_contents .= "{$item['month']}\t";
1537
			$crontab_contents .= "{$item['wday']}\t";
1538
			$crontab_contents .= "{$item['who']}\t";
1539
			$crontab_contents .= "{$item['command']}";
1540
		}
1541
    
1542
		$crontab_contents .= "\n#\n";
1543
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1544
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1545
		$crontab_contents .= "#\n\n";
1546
	}
1547
	
1548
	/* please maintain the newline at the end of file */
1549
	file_put_contents("/etc/crontab", $crontab_contents);
1550

    
1551
	/* do a HUP kill to force sync changes */
1552
	exec('/bin/pkill -HUP cron');
1553

    
1554
	conf_mount_ro();
1555
}
1556

    
1557
function upnp_action ($action) {
1558
	switch($action) {
1559
		case "start":
1560
			if(file_exists('/var/etc/miniupnpd.conf'))
1561
				mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf');
1562
			break;
1563
		case "stop":
1564
			while((int)exec("pgrep miniupnpd | wc -l") > 0)
1565
				mwexec('killall miniupnpd 2>/dev/null', true);
1566
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1567
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1568
			break;
1569
		case "restart":
1570
			upnp_action('stop');
1571
			upnp_action('start');
1572
			break;
1573
	}
1574
}
1575

    
1576
function upnp_start() {
1577
	global $config, $g;
1578

    
1579
	if(!isset($config['installedpackages']['miniupnpd']['config']))
1580
		return;
1581

    
1582
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1583
		if($g['booting']) {
1584
			echo "Starting UPnP service... ";
1585
			require_once('/usr/local/pkg/miniupnpd.inc');
1586
			sync_package_miniupnpd();
1587
			echo "done.\n";
1588
		}
1589
		else {
1590
			upnp_action('start');
1591
		}
1592
	}
1593
}
1594

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

    
1598
	$is_installed = false;
1599

    
1600
	if(!$config['cron']['item'])
1601
		return;
1602

    
1603
	$x=0;
1604
	foreach($config['cron']['item'] as $item) {
1605
		if(strstr($item['command'], $command)) {
1606
			$is_installed = true;
1607
			break;
1608
		}
1609
		$x++;
1610
	}
1611

    
1612
	if($active) {
1613
		$cron_item = array();
1614
		$cron_item['minute'] = $minute;
1615
		$cron_item['hour'] = $hour;
1616
		$cron_item['mday'] = $monthday;
1617
		$cron_item['month'] = $month;
1618
		$cron_item['wday'] = $weekday;
1619
		$cron_item['who'] = $who;
1620
		$cron_item['command'] = $command;
1621
		if(!$is_installed) {
1622
			$config['cron']['item'][] = $cron_item;
1623
			write_config("Installed cron job for {$command}");
1624
		} else {
1625
			$config['cron']['item'][$x] = $cron_item;
1626
			write_config("Updated cron job for {$command}");
1627
		}
1628
	} else {
1629
		if(($is_installed == true) && ($x > 0)) {
1630
			unset($config['cron']['item'][$x]);
1631
			write_config("Remvoed cron job for {$command}");
1632
		}
1633
	}
1634
	configure_cron();
1635
}
1636

    
1637
?>
(37-37/54)