Project

General

Profile

Download (33.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services.inc
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

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

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

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

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

    
32
/* include all configuration functions */
33
require_once("functions.inc");
34

    
35
function services_dhcpd_configure() {
36
	global $config, $g;
37
	if(isset($config['system']['developerspew'])) {
38
		$mt = microtime();
39
		echo "services_dhcpd_configure($if) being called $mt\n";
40
	}
41

    
42
	/* if OLSRD is enabled, allow WAN to house DHCP. */
43
	if($config['installedpackages']['olsrd'])
44
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
45
				if($olsrd['enable'])
46
					$is_olsr_enabled = true;
47

    
48
	/* configure DHCPD chroot */
49
	$fd = fopen("/tmp/dhcpd.sh","w");
50
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
51
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
52
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
53
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
54
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
55
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
56
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
57
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
58
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
59
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
60
	fwrite($fd, "cp /lib/libc.so.6 {$g['dhcpd_chroot_path']}/lib/\n");
61
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
62
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
63
	if(!trim($status))
64
		fwrite($fd, "mount_devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
65
	fclose($fd);
66
	mwexec("/bin/sh /tmp/dhcpd.sh");
67

    
68
	/* kill any running dhcpd */
69
	if(is_process_running("dhcpd"))
70
		mwexec("killall dhcpd");
71

    
72
	$syscfg = $config['system'];
73
	$dhcpdcfg = $config['dhcpd'];
74

    
75
	/* DHCP enabled on any interfaces? */
76
	$dhcpdenable = false;
77
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
78
		if (isset($dhcpifconf['enable']) &&
79
			(($dhcpif == "lan") ||
80
			(isset($config['interfaces'][$dhcpif]['enable']) &&
81
			$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
82
			$dhcpdenable = true;
83
		if (isset($dhcpifconf['enable']) &&
84
			(($dhcpif == "wan") || (isset($config['interfaces'][$dhcpif]['enable']) &&
85
			$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
86
			$dhcpdenable = true;
87
	}
88

    
89
	if (!$dhcpdenable)
90
		return 0;
91

    
92
	if ($g['booting'])
93
		echo "Starting DHCP service...";
94
	else
95
		sleep(1);
96

    
97
	/* write dhcpd.conf */
98
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
99
	if (!$fd) {
100
		printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
101
		return 1;
102
	}
103

    
104

    
105

    
106
	$dhcpdconf = <<<EOD
107
option domain-name "{$syscfg['domain']}";
108
default-lease-time 7200;
109
max-lease-time 86400;
110
authoritative;
111
log-facility local7;
112
ddns-update-style none;
113
one-lease-per-client true;
114
deny duplicates;
115

    
116
EOD;
117

    
118
	$dhcpdifs = array();
119

    
120
	/*    loop through and deterimine if we need to setup
121
	 *    failover peer "bleh" entries
122
	 */
123
	$dhcpnum = 0;
124
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
125
		if($dhcpifconf['failover_peerip'] <> "") {
126
			/*
127
			 *    yep, failover peer is defined.
128
			 *    does it match up to a defined vip?
129
			 */
130
			$skew = 110;
131
			$a_vip = &$config['virtualip']['vip'];
132
			if(is_array($a_vip)) {
133
				foreach ($a_vip as $vipent) {
134
					$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
135
					$intip = find_interface_ip($int);
136
					$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
137
					if($int == $real_dhcpif) {
138
						/* this is the interface! */
139
						if($vipent['advskew'] < "20")
140
							$skew = 0;
141
					}
142
				}
143
			} else {
144
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
145
			}
146
			if($skew > 10) {
147
				$type = "secondary";
148
				$dhcpdconf_pri  = "mclt 600;\n";
149
				$my_port = "520";
150
				$peer_port = "519";
151
			} else {
152
				$my_port = "519";
153
				$peer_port = "520";
154
				$type = "primary";
155
				$dhcpdconf_pri  = "split 128;\n";
156
				$dhcpdconf_pri .= "  mclt 600;\n";
157
			}
158
			$dhcpdconf .= <<<EOPP
159
failover peer "dhcp{$dhcpnum}" {
160
  {$type};
161
  address {$intip};
162
  port {$my_port};
163
  peer address {$dhcpifconf['failover_peerip']};
164
  peer port {$peer_port};
165
  max-response-delay 60;
166
  max-unacked-updates 10;
167
  {$dhcpdconf_pri}
168
  load balance max seconds 3;
169
}
170

    
171
EOPP;
172
		$dhcpnum++;
173
		}
174
	}
175

    
176
	$dhcpnum = 0;
177

    
178
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
179

    
180
		$ifcfg = $config['interfaces'][$dhcpif];
181

    
182
		if (!isset($dhcpifconf['enable']) ||
183
			($ifcfg['ipaddr'] == "dhcp") ||
184
			(($dhcpif != "lan") &&
185
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
186
			continue;
187

    
188
		if($dhcpif == "lan" && $ifcfg['bridge'])
189
			continue;
190

    
191
		$subnet = gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);
192
		$subnetmask = gen_subnet_mask($ifcfg['subnet']);
193

    
194
		if($is_olsr_enabled == true)
195
			if($dhcpifconf['netmask'])
196
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
197

    
198
		$dnscfg = "";
199

    
200
		if ($dhcpifconf['domain']) {
201
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
202
		}
203
		if (isset($dhcpifconf['ddnsupdate'])) {
204
			if($dhcpifconf['ddnsdomain'] <> "") {
205
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
206
			}
207
			$dnscfg .= "	ddns-update-style interim;\n";
208
		}
209

    
210

    
211
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
212
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
213
		} else if (isset($config['dnsmasq']['enable'])) {
214
			$dnscfg .= "	option domain-name-servers " . $ifcfg['ipaddr'] . ";";
215
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
216
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
217
		}
218

    
219
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
220
		$dhcpdconf .= "	pool {\n";
221

    
222
		/* is failover dns setup? */
223
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
224
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
225
			if($dhcpifconf['dnsserver'][1] <> "")
226
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
227
			$dhcpdconf .= ";\n";
228
		}
229

    
230
		if($dhcpifconf['failover_peerip'] <> "")
231
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
232

    
233
		if (isset($dhcpifconf['denyunknown']))
234
		   $dhcpdconf .= "		deny unknown clients;\n";
235

    
236
		if ($dhcpifconf['gateway'])
237
			$routers = $dhcpifconf['gateway'];
238
		else
239
			$routers = $ifcfg['ipaddr'];
240

    
241
		if($dhcpifconf['failover_peerip'] <> "") {
242
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
243
			$dhcpnum++;
244
		}
245

    
246
		$dhcpdconf .= <<<EOD
247
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
248
	}
249
	option routers {$routers};
250
$dnscfg
251

    
252
EOD;
253

    
254
		if ($dhcpifconf['defaultleasetime'])
255
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
256
		if ($dhcpifconf['maxleasetime'])
257
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
258

    
259
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
260
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
261
			$dhcpdconf .= "	option netbios-node-type 8;\n";
262
		}
263

    
264
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
265
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
266

    
267
		if(isset($dhcpifconf['netboot'])) {
268
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
269
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
270
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
271
			}
272
		}
273
		$dhcpdconf .= <<<EOD
274
}
275

    
276
EOD;
277

    
278
		/* add static mappings */
279
		if (is_array($dhcpifconf['staticmap'])) {
280

    
281
			$i = 0;
282
			foreach ($dhcpifconf['staticmap'] as $sm) {
283
				$dhcpdconf .= <<<EOD
284
host s_{$dhcpif}_{$i} {
285
	hardware ethernet {$sm['mac']};
286

    
287
EOD;
288
				if ($sm['ipaddr'])
289
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
290

    
291
				$dhcpdconf .= "}\n";
292
				$i++;
293
			}
294
		}
295

    
296
		$dhcpdifs[] = $ifcfg['if'];
297
	}
298

    
299
	fwrite($fd, $dhcpdconf);
300
	fclose($fd);
301

    
302
	/* create an empty leases database */
303
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
304

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

    
309
	if ($g['booting']) {
310
		print "done.\n";
311
	}
312

    
313
	return 0;
314
}
315

    
316
function interfaces_staticarp_configure($if) {
317
	global $config, $g;
318
	if(isset($config['system']['developerspew'])) {
319
		$mt = microtime();
320
		echo "interfaces_staticarp_configure($if) being called $mt\n";
321
	}
322

    
323
        $ifcfg = $config['interfaces'][$if];
324

    
325
        /* Enable staticarp, if enabled */
326
        if(isset($config['dhcpd'][$if]['staticarp'])) {
327
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
328
                mwexec("/usr/sbin/arp -ad > /dev/null 2>&1 ");
329
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
330

    
331
                        foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
332
                                mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
333
								log_error("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
334
                        }
335

    
336
                }
337
        } else {
338
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
339
                mwexec("/usr/sbin/arp -da > /dev/null 2>&1 ");
340
        }
341

    
342
        return 0;
343
}
344

    
345
function services_dhcrelay_configure() {
346
	global $config, $g;
347
	if(isset($config['system']['developerspew'])) {
348
		$mt = microtime();
349
		echo "services_dhcrelay_configure() being called $mt\n";
350
	}
351

    
352
	/* kill any running dhcrelay */
353
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
354

    
355
	$dhcrelaycfg = $config['dhcrelay'];
356

    
357
	/* DHCPRelay enabled on any interfaces? */
358
	$dhcrelayenable = false;
359
	if(is_array($dhcrelaycfg)) {
360
		foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
361
			if (isset($dhcrelayifconf['enable']) &&
362
				(($dhcrelayif == "lan") ||
363
				(isset($config['interfaces'][$dhcrelayif]['enable']) &&
364
				$config['interfaces'][$dhcrelayif]['if'] && (!$config['interfaces'][$dhcrelayif]['bridge']))))
365
				$dhcrelayenable = true;
366
		}
367
	}
368

    
369
	if (!$dhcrelayenable)
370
		return 0;
371

    
372
	if ($g['booting'])
373
		echo "Starting DHCP relay service...";
374
	else
375
		sleep(1);
376

    
377
	$dhcrelayifs = array();
378
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
379

    
380
		$ifcfg = $config['interfaces'][$dhcrelayif];
381

    
382
		if (!isset($dhcrelayifconf['enable']) ||
383
			(($dhcrelayif != "lan") &&
384
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
385
			continue;
386

    
387
		$dhcrelayifs[] = $ifcfg['if'];
388
	}
389

    
390
	/* In order for the relay to work, it needs to be active on the
391
	   interface in which the destination server sits */
392
	foreach ($config['interfaces'] as $ifname) {
393
		$subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
394
		if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
395
			$destif = $ifname['if'];
396
	}
397

    
398
	if (!isset($destif))
399
		$destif = $config['interfaces']['wan']['if'];
400

    
401
	$dhcrelayifs[] = $destif;
402
	$dhcrelayifs = array_unique($dhcrelayifs);
403

    
404
	/* fire up dhcrelay */
405
	$cmd = "/usr/local/sbin/dhcrelay -i " .  join(" -i ", $dhcrelayifs);
406

    
407
	if (isset($dhcrelaycfg['agentoption']))
408
		$cmd .=  " -a -m replace";
409

    
410
	$cmd .= " {$dhcrelaycfg['server']}";
411
	mwexec($cmd);
412

    
413
	if (!$g['booting']) {
414
		/* set the reload filter dity flag */
415
		touch("{$g['tmp_path']}/filter_dirty");
416
	}
417

    
418
	return 0;
419
}
420

    
421
function services_dyndns_reset() {
422
	global $config, $g;
423
	if(isset($config['system']['developerspew'])) {
424
		$mt = microtime();
425
		echo "services_dyndns_reset() being called $mt\n";
426
	}
427

    
428
	if (file_exists("{$g['vardb_path']}/ez-ipupdate.cache")) {
429
		conf_mount_rw();
430
		unlink("{$g['vardb_path']}/ez-ipupdate.cache");
431
		conf_mount_ro();
432
	}
433

    
434
	if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
435
		conf_mount_rw();
436
		unlink("{$g['conf_path']}/ez-ipupdate.cache");
437
		conf_mount_ro();
438
	}
439

    
440
	return 0;
441
}
442

    
443
function services_dyndns_configure() {
444
	global $config, $g;
445
	if(isset($config['system']['developerspew'])) {
446
		$mt = microtime();
447
		echo "services_dyndns_configure() being called $mt\n";
448
	}
449

    
450
	$dyndnscfg = $config['dyndns'];
451
	$wancfg = $config['interfaces']['wan'];
452

    
453
	if (isset($dyndnscfg['enable'])) {
454

    
455
		if ($g['booting']) {
456
			echo "Starting DynDNS client...";
457
			if(isset($config['system']['use_old_dyndns'])) {
458
				echo " [Using ez-ipupdate] ";
459
				services_dyndns_configure_old();
460
				return;
461
			}
462
		} else {
463
			sleep(1);
464
			if(isset($config['system']['use_old_dyndns'])) {
465
				services_dyndns_configure_old();
466
				return;
467
			}
468
		}
469

    
470
		/* load up the dyndns.class */
471
		require_once("dyndns.class");
472

    
473
		log_error("DynDns: Running updatedns()");
474

    
475
		/* determine WAN interface name */
476
		$wanif = get_real_wan_interface();
477
		/* get ip */
478
		$ip = find_interface_ip($wanif);
479

    
480
		$dns = new updatedns($dnsService = $config['dyndns']['type'],
481
							 $dnsHost = $config['dyndns']['host'],
482
							 $dnsUser = $config['dyndns']['username'],
483
							 $dnsPass = $config['dyndns']['password'],
484
							 $dnsWilcard = $config['dyndns']['wildcard'],
485
							 $dnsMX = $config['dyndns']['mx']);
486

    
487
		if ($g['booting'])
488
			echo "done.\n";
489
	}
490

    
491
	return 0;
492
}
493

    
494
function services_dyndns_configure_old() {
495
	global $config, $g;
496
	if(isset($config['system']['developerspew'])) {
497
		$mt = microtime();
498
		echo "services_dyndns_configure_old() being called $mt\n";
499
	}
500

    
501
        /* kill any running ez-ipupdate */
502
        /* ez-ipupdate needs SIGQUIT instead of SIGTERM */
503
        sigkillbypid("{$g['varrun_path']}/ez-ipupdate.pid", "QUIT");
504

    
505
        $dyndnscfg = $config['dyndns'];
506
        $wancfg = $config['interfaces']['wan'];
507

    
508
        if (isset($dyndnscfg['enable'])) {
509

    
510
                if ($g['booting'])
511
                        echo "Starting DynDNS client...";
512
                else
513
                        sleep(1);
514

    
515
                /* determine WAN interface name */
516
                $wanif = get_real_wan_interface();
517

    
518
                /* write ez-ipupdate.conf */
519
                $fd = fopen("{$g['varetc_path']}/ez-ipupdate.conf", "w");
520
                if (!$fd) {
521
                        printf("Error: cannot open ez-ipupdate.conf in services_dyndns_configure().\n");
522
                        return 1;
523
                }
524

    
525
                $ezipupdateconf = <<<EOD
526
service-type={$dyndnscfg['type']}
527
user={$dyndnscfg['username']}:{$dyndnscfg['password']}
528
host={$dyndnscfg['host']}
529
interface={$wanif}
530
max-interval=2073600
531
pid-file={$g['varrun_path']}/ez-ipupdate.pid
532
cache-file={$g['vardb_path']}/ez-ipupdate.cache
533
execute=/etc/rc.dyndns.storecache
534
daemon
535

    
536
EOD;
537

    
538
                /* enable server[:port]? */
539
                if ($dyndnscfg['server']) {
540
                        if ($dyndnscfg['port'])
541
                                $ezipupdateconf .= "server={$dyndnscfg['server']}:{$dyndnscfg['port']}\n";
542
                        else
543
                                $ezipupdateconf .= "server={$dyndnscfg['server']}\n";
544
                }
545

    
546
                /* enable MX? */
547
                if ($dyndnscfg['mx']) {
548
                        $ezipupdateconf .= "mx={$dyndnscfg['mx']}\n";
549
                }
550

    
551
                /* enable wildcards? */
552
                if (isset($dyndnscfg['wildcard'])) {
553
                        $ezipupdateconf .= "wildcard\n";
554
                }
555

    
556
                fwrite($fd, $ezipupdateconf);
557
                fclose($fd);
558

    
559
                /* if we're booting, copy the cache file from /conf */
560
                if ($g['booting']) {
561
                        if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
562
                                copy("{$g['conf_path']}/ez-ipupdate.cache", "{$g['vardb_path']}/ez-ipupdate.cache");
563
                       }
564
                }
565

    
566
                /* run ez-ipupdate */
567
                mwexec("/usr/local/bin/ez-ipupdate -c {$g['varetc_path']}/ez-ipupdate.conf");
568

    
569
                if ($g['booting'])
570
                        echo "done\n";
571
        }
572

    
573
        return 0;
574
}
575

    
576
function services_dnsmasq_configure() {
577
	global $config, $g;
578
	$return = 0;
579
	
580
	if(isset($config['system']['developerspew'])) {
581
		$mt = microtime();
582
		echo "services_dnsmasq_configure() being called $mt\n";
583
	}
584

    
585
	/* kill any running dnsmasq */
586
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
587

    
588
	if (isset($config['dnsmasq']['enable'])) {
589

    
590
		if ($g['booting'])
591
			echo "Starting DNS forwarder...";
592
		else
593
			sleep(1);
594

    
595
		/* generate hosts file */
596
		if(system_hosts_generate()!=0)
597
			$return = 1;
598

    
599
		$args = "";
600

    
601
		if (isset($config['dnsmasq']['regdhcp'])) {
602

    
603
			$args .= " -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases" .
604
				" -s {$config['system']['domain']}";
605
		}
606

    
607
                if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
608
                        foreach($config['dnsmasq']['domainoverrides'] as $override) {
609
                                $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
610
                        }
611
                }
612

    
613
		/* suppose that dnsmasq handles our domain and don't send
614
		requests for our local domain to upstream servers */
615
		if (!empty($config['system']['domain'])) {
616
			$args .= sprintf(' --local=/%s/', $config['system']['domain']);
617
		}
618

    
619
		/* run dnsmasq */
620
		mwexec("/usr/local/sbin/dnsmasq {$args}");
621

    
622
		if ($g['booting'])
623
			echo "done.\n";
624
	}
625

    
626
	if (!$g['booting']) {
627
		if(services_dhcpd_configure()!=0)
628
			$return = 1;
629
	}
630

    
631
	return $return;
632
}
633

    
634
function services_snmpd_configure() {
635
	global $config, $g;
636
	if(isset($config['system']['developerspew'])) {
637
		$mt = microtime();
638
		echo "services_snmpd_configure() being called $mt\n";
639
	}
640

    
641
	/* kill any running snmpd */
642
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
643
	if(is_process_running("bsnmpd")) 
644
		exec("/usr/bin/killall bsnmpd");
645

    
646
	if (isset($config['snmpd']['enable'])) {
647

    
648
		if ($g['booting'])
649
			echo "Starting SNMP daemon... ";
650

    
651
		/* generate snmpd.conf */
652
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
653
		if (!$fd) {
654
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
655
			return 1;
656
		}
657

    
658

    
659
		$snmpdconf = <<<EOD
660
location := "{$config['snmpd']['syslocation']}"
661
contact := "{$config['snmpd']['syscontact']}"
662
read := "{$config['snmpd']['rocommunity']}"
663

    
664
EOD;
665

    
666
/* No docs on what write strings do there for disable for now.
667
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
668
		    $snmpdconf .= <<<EOD
669
# write string
670
write := "{$config['snmpd']['rwcommunity']}"
671

    
672
EOD;
673
		}
674
*/
675

    
676

    
677
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
678
		    $snmpdconf .= <<<EOD
679
# SNMP Trap support.
680
traphost := {$config['snmpd']['trapserver']}
681
trapport := {$config['snmpd']['trapserverport']}
682
trap := "{$config['snmpd']['trapstring']}"
683

    
684

    
685
EOD;
686
		}
687

    
688

    
689
		$snmpdconf .= <<<EOD
690
system := 1     # pfSense
691
%snmpd
692
begemotSnmpdDebugDumpPdus       = 2
693
begemotSnmpdDebugSyslogPri      = 7
694
begemotSnmpdCommunityString.0.1 = $(read)
695

    
696
EOD;
697

    
698
/* No docs on what write strings do there for disable for now.
699
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
700
		    $snmpdconf .= <<<EOD
701
begemotSnmpdCommunityString.0.2 = $(write)
702

    
703
EOD;
704
		}
705
*/
706

    
707

    
708
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
709
		    $snmpdconf .= <<<EOD
710
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
711
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
712
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
713

    
714
EOD;
715
		}
716

    
717

    
718
		$snmpdconf .= <<<EOD
719
begemotSnmpdCommunityDisable    = 1
720

    
721
EOD;
722

    
723
		if(isset($config['snmpd']['bindlan'])) {
724
			$bind_to_ip = $config['interfaces']['lan']['ipaddr'];
725
		} else {
726
			$bind_to_ip = "0.0.0.0";
727
		}
728

    
729
		if(is_port( $config['snmpd']['pollport'] )) {
730
		    $snmpdconf .= <<<EOD
731
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
732

    
733
EOD;
734

    
735
		}
736

    
737
		$snmpdconf .= <<<EOD
738
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
739
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
740

    
741
# These are bsnmp macros not php vars.
742
sysContact      = $(contact)
743
sysLocation     = $(location)
744
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
745

    
746
snmpEnableAuthenTraps = 2
747

    
748
EOD;
749

    
750
		if (is_array( $config['snmpd']['modules'] )) {
751
		    if(isset($config['snmpd']['modules']['mibii'])) {
752
			$snmpdconf .= <<<EOD
753
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
754

    
755
EOD;
756
		    }
757

    
758
		    if(isset($config['snmpd']['modules']['netgraph'])) {
759
			$snmpdconf .= <<<EOD
760
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
761
%netgraph
762
begemotNgControlNodeName = "snmpd"
763

    
764
EOD;
765
		    }
766

    
767
		    if(isset($config['snmpd']['modules']['pf'])) {
768
			$snmpdconf .= <<<EOD
769
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
770

    
771
EOD;
772
		    }
773

    
774
		    if(isset($config['snmpd']['modules']['hostres'])) {
775
			$snmpdconf .= <<<EOD
776
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
777

    
778
EOD;
779
		    }
780
		    if(isset($config['snmpd']['modules']['bridge'])) {
781
			$snmpdconf .= <<<EOD
782
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
783
# config must end with blank line
784

    
785

    
786
EOD;
787
		    }
788
		}
789

    
790
		fwrite($fd, $snmpdconf);
791
		fclose($fd);
792

    
793
		if (isset($config['snmpd']['bindlan'])) {
794
			$bindlan = "";
795
		}
796

    
797
		/* run bsnmpd */
798
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
799
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
800

    
801
		if ($g['booting'])
802
			echo "done.\n";
803
	}
804

    
805
	return 0;
806
}
807

    
808
function services_proxyarp_configure() {
809
	global $config, $g;
810
	if(isset($config['system']['developerspew'])) {
811
		$mt = microtime();
812
		echo "services_proxyarp_configure() being called $mt\n";
813
	}
814

    
815
	/* kill any running choparp */
816
	killbyname("choparp");
817

    
818
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
819
		$paa = array();
820

    
821
		/* group by interface */
822
		foreach ($config['virtualip']['vip'] as $vipent) {
823
			if ($vipent['mode'] === "proxyarp") {
824
				if ($vipent['interface'])
825
					$if = $vipent['interface'];
826
				else
827
					$if = "wan";
828

    
829
				if (!is_array($paa[$if]))
830
					$paa[$if] = array();
831

    
832
				$paa[$if][] = $vipent;
833
			}
834
		}
835

    
836
		if (count($paa))
837
		foreach ($paa as $paif => $paents) {
838
			if ($paif == "wan" && !(is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
839
                                       ($config['interfaces']['wan']['ipaddr'] == "dhcp") ||
840
                                       ($config['interfaces']['wan']['ipaddr'] == "bigpond")))
841
                               continue;
842

    
843
			$args = $config['interfaces'][$paif]['if'] . " auto";
844

    
845
			foreach ($paents as $paent) {
846

    
847
				if (isset($paent['subnet']))
848
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
849
				else if (isset($paent['range']))
850
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
851
						$paent['range']['to']);
852
			}
853

    
854
			mwexec_bg("/usr/local/sbin/choparp " . $args);
855
		}
856
	}
857
}
858

    
859
function services_dnsupdate_process() {
860
	global $config, $g;
861
	if(isset($config['system']['developerspew'])) {
862
		$mt = microtime();
863
		echo "services_dnsupdate_process() being called $mt\n";
864
	}
865

    
866
	/* Dynamic DNS updating active? */
867
	if (isset($config['dnsupdate']['enable'])) {
868

    
869
		$wanip = get_current_wan_address();
870
		if ($wanip) {
871

    
872
			$keyname = $config['dnsupdate']['keyname'];
873
			/* trailing dot */
874
			if (substr($keyname, -1) != ".")
875
				$keyname .= ".";
876

    
877
			$hostname = $config['dnsupdate']['host'];
878
			/* trailing dot */
879
			if (substr($hostname, -1) != ".")
880
				$hostname .= ".";
881

    
882
			/* write private key file
883
			   this is dumb - public and private keys are the same for HMAC-MD5,
884
			   but nsupdate insists on having both */
885
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.private", "w");
886
			$privkey .= <<<EOD
887
Private-key-format: v1.2
888
Algorithm: 157 (HMAC)
889
Key: {$config['dnsupdate']['keydata']}
890

    
891
EOD;
892
			fwrite($fd, $privkey);
893
			fclose($fd);
894

    
895
			/* write public key file */
896
			if ($config['dnsupdate']['keytype'] == "zone") {
897
				$flags = 257;
898
				$proto = 3;
899
			} else if ($config['dnsupdate']['keytype'] == "host") {
900
				$flags = 513;
901
				$proto = 3;
902
			} else if ($config['dnsupdate']['keytype'] == "user") {
903
				$flags = 0;
904
				$proto = 2;
905
			}
906

    
907
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.key", "w");
908
			fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$config['dnsupdate']['keydata']}\n");
909
			fclose($fd);
910

    
911
			/* generate update instructions */
912
			$upinst =  "update delete {$config['dnsupdate']['host']} A\n";
913
			$upinst .= "update add {$config['dnsupdate']['host']} {$config['dnsupdate']['ttl']} A {$wanip}\n";
914
			$upinst .= "\n";	/* mind that trailing newline! */
915

    
916
			$fd = fopen("{$g['varetc_path']}/nsupdatecmds", "w");
917
			fwrite($fd, $upinst);
918
			fclose($fd);
919

    
920
			/* invoke nsupdate */
921
			$cmd = "/usr/sbin/nsupdate -k {$g['varetc_path']}/K{$keyname}+157+00000.key";
922
			if (isset($config['dnsupdate']['usetcp']))
923
				$cmd .= " -v";
924
			$cmd .= " {$g['varetc_path']}/nsupdatecmds";
925

    
926
			mwexec_bg($cmd);
927
		}
928
	}
929

    
930
	return 0;
931
}
932

    
933
function setup_wireless_olsr() {
934
	global $config, $g;
935
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
936
		return;
937
	if(isset($config['system']['developerspew'])) {
938
		$mt = microtime();
939
		echo "setup_wireless_olsr($interface) being called $mt\n";
940
	}
941
	conf_mount_rw();
942
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
943
		$olsr_enable = $olsrd['enable'];
944
		if($olsr_enable <> "on")
945
			return;
946
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
947

    
948
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
949
			$enableannounce .= "\nHna4\n";
950
			$enableannounce .= "{\n";
951
		if($olsrd['announcedynamicroute'])
952
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
953
		if($olsrd['enableannounce'] == "on")
954
			$enableannounce .= "0.0.0.0 0.0.0.0";
955
			$enableannounce .= "\n}\n";
956
		} else {
957
			$enableannounce = "";
958
		}
959

    
960
		$olsr .= <<<EODA
961
#
962
# olsr.org OLSR daemon config file
963
#
964
# Lines starting with a # are discarded
965
#
966
# This file was generated by setup_wireless_olsr() in services.inc
967
#
968

    
969
# This file is an example of a typical
970
# configuration for a mostly static
971
# network(regarding mobility) using
972
# the LQ extention
973

    
974
# Debug level(0-9)
975
# If set to 0 the daemon runs in the background
976

    
977
DebugLevel	2
978

    
979
# IP version to use (4 or 6)
980

    
981
IpVersion	4
982

    
983
# Clear the screen each time the internal state changes
984

    
985
ClearScreen     yes
986

    
987
{$enableannounce}
988

    
989
# Should olsrd keep on running even if there are
990
# no interfaces available? This is a good idea
991
# for a PCMCIA/USB hotswap environment.
992
# "yes" OR "no"
993

    
994
AllowNoInt	yes
995

    
996
# TOS(type of service) value for
997
# the IP header of control traffic.
998
# If not set it will default to 16
999

    
1000
#TosValue	16
1001

    
1002
# The fixed willingness to use(0-7)
1003
# If not set willingness will be calculated
1004
# dynamically based on battery/power status
1005
# if such information is available
1006

    
1007
#Willingness    	4
1008

    
1009
# Allow processes like the GUI front-end
1010
# to connect to the daemon.
1011

    
1012
IpcConnect
1013
{
1014
     # Determines how many simultaneously
1015
     # IPC connections that will be allowed
1016
     # Setting this to 0 disables IPC
1017

    
1018
     MaxConnections  0
1019

    
1020
     # By default only 127.0.0.1 is allowed
1021
     # to connect. Here allowed hosts can
1022
     # be added
1023

    
1024
     Host            127.0.0.1
1025
     #Host            10.0.0.5
1026

    
1027
     # You can also specify entire net-ranges
1028
     # that are allowed to connect. Multiple
1029
     # entries are allowed
1030

    
1031
     #Net             192.168.1.0 255.255.255.0
1032
}
1033

    
1034
# Wether to use hysteresis or not
1035
# Hysteresis adds more robustness to the
1036
# link sensing but delays neighbor registration.
1037
# Used by default. 'yes' or 'no'
1038

    
1039
UseHysteresis	no
1040

    
1041
# Hysteresis parameters
1042
# Do not alter these unless you know
1043
# what you are doing!
1044
# Set to auto by default. Allowed
1045
# values are floating point values
1046
# in the interval 0,1
1047
# THR_LOW must always be lower than
1048
# THR_HIGH.
1049

    
1050
#HystScaling	0.50
1051
#HystThrHigh	0.80
1052
#HystThrLow	0.30
1053

    
1054

    
1055
# Link quality level
1056
# 0 = do not use link quality
1057
# 1 = use link quality for MPR selection
1058
# 2 = use link quality for MPR selection and routing
1059
# Defaults to 0
1060

    
1061
LinkQualityLevel	{$olsrd['enablelqe']}
1062

    
1063
# Link quality window size
1064
# Defaults to 10
1065

    
1066
LinkQualityWinSize	10
1067

    
1068
# Polling rate in seconds(float).
1069
# Default value 0.05 sec
1070

    
1071
Pollrate	0.05
1072

    
1073

    
1074
# TC redundancy
1075
# Specifies how much neighbor info should
1076
# be sent in TC messages
1077
# Possible values are:
1078
# 0 - only send MPR selectors
1079
# 1 - send MPR selectors and MPRs
1080
# 2 - send all neighbors
1081
#
1082
# defaults to 0
1083

    
1084
TcRedundancy	2
1085

    
1086
#
1087
# MPR coverage
1088
# Specifies how many MPRs a node should
1089
# try select to reach every 2 hop neighbor
1090
#
1091
# Can be set to any integer >0
1092
#
1093
# defaults to 1
1094

    
1095
MprCoverage	3
1096

    
1097
# Example plugin entry with parameters:
1098

    
1099
EODA;
1100

    
1101
if($olsrd['enablehttpinfo'] == "on") {
1102
	$olsr .= <<<EODB
1103

    
1104
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1105
{
1106
    PlParam     "port"   "{$olsrd['port']}"
1107
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1108
}
1109

    
1110
EODB;
1111

    
1112
}
1113

    
1114
if($olsrd['enabledsecure'] == "on") {
1115
	$olsr .= <<<EODC
1116

    
1117
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1118
{
1119
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1120
}
1121

    
1122
EODC;
1123

    
1124
}
1125

    
1126
if($olsrd['enabledyngw'] == "on") {
1127

    
1128
	/* unset default route, olsr auto negotiates */
1129
	mwexec("/sbin/route delete default");
1130

    
1131
	$olsr .= <<<EODE
1132

    
1133
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1134
{
1135
    # how often to look for a inet gw, in seconds
1136
    # defaults to 5 secs, if commented out
1137
    PlParam     "Interval"   "{$olsrd['polling']}"
1138

    
1139
    # if one or more IPv4 addresses are given, do a ping on these in
1140
    # descending order to validate that there is not only an entry in
1141
    # routing table, but also a real internet connection. If any of
1142
    # these addresses could be pinged successfully, the test was
1143
    # succesful, i.e. if the ping on the 1st address was successful,the
1144
    # 2nd won't be pinged
1145
    PlParam     "Ping"       "{$olsrd['ping']}"
1146
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1147
}
1148

    
1149
EODE;
1150

    
1151
}
1152

    
1153
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1154
	$interfaces = explode(',', $conf['iface_array']);
1155
	foreach($interfaces as $interface) {
1156
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1157
$olsr .= <<<EODAD
1158
Interface "{$realinterface}"
1159
{
1160

    
1161
    # Hello interval in seconds(float)
1162
    HelloInterval    2.0
1163

    
1164
    # HELLO validity time
1165
    HelloValidityTime	20.0
1166

    
1167
    # TC interval in seconds(float)
1168
    TcInterval        5.0
1169

    
1170
    # TC validity time
1171
    TcValidityTime	30.0
1172

    
1173
    # MID interval in seconds(float)
1174
    MidInterval	5.0
1175

    
1176
    # MID validity time
1177
    MidValidityTime	30.0
1178

    
1179
    # HNA interval in seconds(float)
1180
    HnaInterval	5.0
1181

    
1182
    # HNA validity time
1183
    HnaValidityTime 	30.0
1184

    
1185
    # When multiple links exist between hosts
1186
    # the weight of interface is used to determine
1187
    # the link to use. Normally the weight is
1188
    # automatically calculated by olsrd based
1189
    # on the characteristics of the interface,
1190
    # but here you can specify a fixed value.
1191
    # Olsrd will choose links with the lowest value.
1192

    
1193
    # Weight 0
1194

    
1195

    
1196
}
1197

    
1198
EODAD;
1199

    
1200
	}
1201
	break;
1202
}
1203
		fwrite($fd, $olsr);
1204
		fclose($fd);
1205
	}
1206

    
1207
	if(is_process_running("olsrd"))
1208
		mwexec("/usr/bin/killall olsrd");
1209

    
1210
	sleep(2);
1211

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

    
1214
	conf_mount_ro();
1215
}
1216

    
1217
/* configure cron service */
1218
function configure_cron() {
1219
	global $g, $config;
1220
	if (!$g['booting'])
1221
		conf_mount_rw();
1222
	/* preserve existing crontab entries */
1223
	$crontab_contents = file_get_contents("/etc/crontab");
1224
	$crontab_contents_a = split("\n", $crontab_contents);
1225
	
1226
	for ($i = 0; $i < count($crontab_contents_a); $i++) {
1227
		$item =& $crontab_contents_a[$i];
1228
		if (strpos($item, "# pfSense specific crontab entries") !== false) {
1229
			array_splice($crontab_contents_a, $i - 1);
1230
			break;
1231
		}
1232
	}
1233
	$crontab_contents = implode("\n", $crontab_contents_a) . "\n";
1234
	
1235
	
1236
	if (is_array($config['cron']['item'])) {
1237
		$crontab_contents .= "#\n";
1238
		$crontab_contents .= "# pfSense specific crontab entries\n";
1239
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1240
		$crontab_contents .= "#\n";
1241

    
1242
		foreach ($config['cron']['item'] as $item) {
1243
			$crontab_contents .= "\n{$item['minute']}\t";
1244
			$crontab_contents .= "{$item['hour']}\t";
1245
			$crontab_contents .= "{$item['mday']}\t";
1246
			$crontab_contents .= "{$item['month']}\t";
1247
			$crontab_contents .= "{$item['wday']}\t";
1248
			$crontab_contents .= "{$item['who']}\t";
1249
			$crontab_contents .= "{$item['command']}";
1250
		}
1251
    
1252
		$crontab_contents .= "\n#\n";
1253
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1254
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1255
		$crontab_contents .= "#\n\n";
1256
	}
1257
	
1258
	/* please maintain the newline at the end of file */
1259
	file_put_contents("/etc/crontab", $crontab_contents);
1260
	
1261
	if (!$g['booting'])
1262
		conf_mount_ro();
1263
}
1264

    
1265
?>
(18-18/27)