Project

General

Profile

Download (16.2 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
require_once("dyndns.class");
35

    
36
function services_dhcpd_configure() {
37
	global $config, $g;
38

    
39
	/* kill any running dhcpd */
40
	killbypid("{$g['varrun_path']}/dhcpd.pid");
41

    
42
	$syscfg = $config['system'];
43
	$dhcpdcfg = $config['dhcpd'];
44

    
45
	/* DHCP enabled on any interfaces? */
46
	$dhcpdenable = false;
47
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
48
		if (isset($dhcpifconf['enable']) &&
49
			(($dhcpif == "lan") ||
50
			(isset($config['interfaces'][$dhcpif]['enable']) &&
51
			$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
52
			$dhcpdenable = true;
53
	}
54

    
55
	if (!$dhcpdenable)
56
		return 0;
57

    
58
	if ($g['booting'])
59
		echo "Starting DHCP service... ";
60
	else
61
		sleep(1);
62

    
63
	/* write dhcpd.conf */
64
	$fd = fopen("{$g['varetc_path']}/dhcpd.conf", "w");
65
	if (!$fd) {
66
		printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
67
		return 1;
68
	}
69

    
70
	$dhcpdconf = <<<EOD
71
option domain-name "{$syscfg['domain']}";
72
default-lease-time 7200;
73
max-lease-time 86400;
74
authoritative;
75
log-facility local7;
76
ddns-update-style none;
77

    
78
EOD;
79

    
80
	$dhcpdifs = array();
81
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
82

    
83
		$ifcfg = $config['interfaces'][$dhcpif];
84

    
85
		if (!isset($dhcpifconf['enable']) ||
86
			(($dhcpif != "lan") &&
87
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
88
			continue;
89

    
90
		$subnet = gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);
91
		$subnetmask = gen_subnet_mask($ifcfg['subnet']);
92

    
93
		$dnscfg = "";
94

    
95
		if ($dhcpifconf['domain']) {
96
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
97
		}
98

    
99
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
100
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
101
		} else if (isset($config['dnsmasq']['enable'])) {
102
			$dnscfg .= "	option domain-name-servers " . $ifcfg['ipaddr'] . ";";
103
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
104
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
105
		}
106

    
107
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
108
		$dhcpdconf .= "	pool {\n";
109
		if (isset($dhcpifconf['denyunknown']))
110
		   $dhcpdconf .= "		deny unknown clients;\n";
111

    
112
		if ($dhcpifconf['gateway'])
113
			$routers = $dhcpifconf['gateway'];
114
		else
115
			$routers = $ifcfg['ipaddr'];
116

    
117
		$dhcpdconf .= <<<EOD
118
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
119
	}
120
	option routers {$routers};
121
$dnscfg
122

    
123
EOD;
124

    
125
		if ($dhcpifconf['defaultleasetime'])
126
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
127
		if ($dhcpifconf['maxleasetime'])
128
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
129

    
130
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
131
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
132
			$dhcpdconf .= "	option netbios-node-type 8;\n";
133
		}
134

    
135
		if ($dhcpifconf['next-server'])
136
			$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
137
		if ($dhcpifconf['filename'])
138
			$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
139

    
140
		$dhcpdconf .= <<<EOD
141
}
142

    
143
EOD;
144

    
145
		/* add static mappings */
146
		if (is_array($dhcpifconf['staticmap'])) {
147

    
148
			$i = 0;
149
			foreach ($dhcpifconf['staticmap'] as $sm) {
150
				$dhcpdconf .= <<<EOD
151
host s_{$dhcpif}_{$i} {
152
	hardware ethernet {$sm['mac']};
153

    
154
EOD;
155
				if ($sm['ipaddr'])
156
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
157

    
158
				$dhcpdconf .= "}\n";
159
				$i++;
160
			}
161
		}
162

    
163
		$dhcpdifs[] = $ifcfg['if'];
164
	}
165

    
166
	fwrite($fd, $dhcpdconf);
167
	fclose($fd);
168

    
169
	/* create an empty leases database */
170
	touch("{$g['vardb_path']}/dhcpd.leases");
171

    
172
	/* fire up dhcpd */
173
	mwexec("/usr/local/sbin/dhcpd -cf {$g['varetc_path']}/dhcpd.conf " .
174
		join(" ", $dhcpdifs));
175

    
176
	if ($g['booting']) {
177
                print "done.\n";
178
	}
179

    
180
	return 0;
181
}
182

    
183
function interfaces_staticarp_configure($if) {
184
        global $config, $g;
185
        
186
        $ifcfg = $config['interfaces'][$if];
187

    
188
        /* Enable staticarp, if enabled */
189
        if(isset($config['dhcpd'][$if]['staticarp'])) {
190
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
191
                mwexec("/usr/sbin/arp -ad > /dev/null 2>&1 ");
192
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
193

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

    
197
                        }
198
                        
199
                }
200
        } else {
201
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
202
                mwexec("/usr/sbin/arp -ad > /dev/null 2>&1 ");
203
        }
204

    
205
        return 0;
206
}
207

    
208
function services_dhcrelay_configure() {
209
	global $config, $g;
210

    
211
	/* kill any running dhcrelay */
212
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
213

    
214
	$dhcrelaycfg = $config['dhcrelay'];
215

    
216
	/* DHCPRelay enabled on any interfaces? */
217
	$dhcrelayenable = false;
218
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
219
		if (isset($dhcrelayifconf['enable']) &&
220
			(($dhcrelayif == "lan") ||
221
			(isset($config['interfaces'][$dhcrelayif]['enable']) &&
222
			$config['interfaces'][$dhcrelayif]['if'] && (!$config['interfaces'][$dhcrelayif]['bridge']))))
223
			$dhcrelayenable = true;
224
	}
225

    
226
	if (!$dhcrelayenable)
227
		return 0;
228

    
229
	if ($g['booting'])
230
		echo "Starting DHCP relay service... ";
231
	else
232
		sleep(1);
233

    
234
	$dhcrelayifs = array();
235
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
236

    
237
		$ifcfg = $config['interfaces'][$dhcrelayif];
238

    
239
		if (!isset($dhcrelayifconf['enable']) ||
240
			(($dhcrelayif != "lan") &&
241
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
242
			continue;
243

    
244
		$dhcrelayifs[] = $ifcfg['if'];
245
	}
246

    
247
	/* In order for the relay to work, it needs to be active on the
248
	   interface in which the destination server sits */
249
	foreach ($config['interfaces'] as $ifname) {
250
		$subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
251
		if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
252
			$destif = $ifname['if'];
253
	}
254

    
255
	if (!isset($destif))
256
		$destif = $config['interfaces']['wan']['if'];
257

    
258
	$dhcrelayifs[] = $destif;
259
	$dhcrelayifs = array_unique($dhcrelayifs);
260

    
261
	/* fire up dhcrelay */
262
	$cmd = "/usr/local/sbin/dhcrelay -i " .  join(" -i ", $dhcrelayifs);
263

    
264
	if (isset($dhcrelaycfg['agentoption']))
265
		$cmd .=  " -a -m replace";
266

    
267
	$cmd .= " {$dhcrelaycfg['server']}";
268
	mwexec($cmd);
269

    
270
	if (!$g['booting']) {
271
		/* set the reload filter dity flag */
272
		touch("{$g['tmp_path']}/filter_dirty");
273
	}
274

    
275
	return 0;
276
}
277

    
278
function services_dyndns_reset() {
279
	global $config, $g;
280

    
281
	if (file_exists("{$g['vardb_path']}/ez-ipupdate.cache")) {
282
		unlink("{$g['vardb_path']}/ez-ipupdate.cache");
283
	}
284

    
285
	if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
286
		conf_mount_rw();
287
		unlink("{$g['conf_path']}/ez-ipupdate.cache");
288
		conf_mount_ro();
289
	}
290

    
291
	return 0;
292
}
293

    
294
function services_dyndns_configure() {
295
	global $config, $g;
296

    
297
	$dyndnscfg = $config['dyndns'];
298
	$wancfg = $config['interfaces']['wan'];
299

    
300
	if (isset($dyndnscfg['enable'])) {
301

    
302
		if ($g['booting'])
303
			echo "Starting DynDNS client... ";
304
		else
305
			sleep(1);
306

    
307
		$dns = new updatedns($dnsService = $config['dyndns']['type'],
308
							 $dnsHost = $config['dyndns']['host'],
309
							 $dnsUser = $config['dyndns']['username'],
310
							 $dnsPass = $config['dyndns']['password'],
311
							 $dnsWilcard = $config['dyndns']['wildcard'],
312
							 $dnsMX = $config['dyndns']['mx']);
313

    
314
		if ($g['booting'])
315
			echo "done.\n";
316
	}
317

    
318
	return 0;
319
}
320

    
321
function services_dnsmasq_configure() {
322
	global $config, $g;
323

    
324
	/* kill any running dnsmasq */
325
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
326

    
327
	if (isset($config['dnsmasq']['enable'])) {
328

    
329
		if ($g['booting'])
330
			echo "Starting DNS forwarder... ";
331
		else
332
			sleep(1);
333

    
334
		/* generate hosts file */
335
		system_hosts_generate();
336

    
337
		$args = "";
338

    
339
		if (isset($config['dnsmasq']['regdhcp'])) {
340

    
341
			$args .= " -l {$g['vardb_path']}/dhcpd.leases" .
342
				" -s {$config['system']['domain']}";
343
		}
344

    
345
                if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
346
                        foreach($config['dnsmasq']['domainoverrides'] as $override) {
347
                                $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
348
                        }
349
                }
350

    
351
		/* run dnsmasq */
352
		mwexec("/usr/local/sbin/dnsmasq {$args}");
353

    
354
		if ($g['booting'])
355
			echo "done.\n";
356
	}
357

    
358
	if (!$g['booting']) {
359
		services_dhcpd_configure();
360
	}
361

    
362
	return 0;
363
}
364

    
365
function services_snmpd_configure() {
366
	global $config, $g;
367

    
368
	/* kill any running snmpd */
369
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
370

    
371
	if (isset($config['snmpd']['enable'])) {
372

    
373
		if ($g['booting'])
374
			echo "Starting SNMP daemon... ";
375

    
376
		/* generate snmpd.conf */
377
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
378
		if (!$fd) {
379
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
380
			return 1;
381
		}
382

    
383

    
384
		$snmpdconf = <<<EOD
385
location := "{$config['snmpd']['syslocation']}"
386
contact := "{$config['snmpd']['syscontact']}"
387
read := "{$config['snmpd']['rocommunity']}"
388

    
389
EOD;
390

    
391
/* No docs on what write strings do there for disable for now.
392
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
393
		    $snmpdconf .= <<<EOD
394
# write string
395
write := "{$config['snmpd']['rwcommunity']}"
396

    
397
EOD;
398
		}
399
*/
400

    
401

    
402
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
403
		    $snmpdconf .= <<<EOD
404
# SNMP Trap support.
405
traphost := {$config['snmpd']['trapserver']}
406
trapport := {$config['snmpd']['trapserverport']}
407
trap := "{$config['snmpd']['trapstring']}"
408

    
409

    
410
EOD;
411
		}
412

    
413

    
414
		$snmpdconf .= <<<EOD
415
system := 1     # pfSense
416
%snmpd
417
begemotSnmpdDebugDumpPdus       = 2
418
begemotSnmpdDebugSyslogPri      = 7
419
begemotSnmpdCommunityString.0.1 = $(read)
420

    
421
EOD;
422

    
423
/* No docs on what write strings do there for disable for now.
424
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
425
		    $snmpdconf .= <<<EOD
426
begemotSnmpdCommunityString.0.2 = $(write)
427

    
428
EOD;
429
		}
430
*/
431

    
432
		
433
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
434
		    $snmpdconf .= <<<EOD
435
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
436
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
437
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
438

    
439
EOD;
440
		}
441

    
442

    
443
		$snmpdconf .= <<<EOD
444
begemotSnmpdCommunityDisable    = 1
445

    
446
EOD;
447

    
448
		if(is_port( $config['snmpd']['pollport'] )) {
449
		    $snmpdconf .= <<<EOD
450
begemotSnmpdPortStatus.0.0.0.0.{$config['snmpd']['pollport']} = 1
451

    
452
EOD;
453

    
454
		}
455

    
456
		$snmpdconf .= <<<EOD
457
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
458
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
459

    
460
# These are bsnmp macros not php vars.
461
sysContact      = $(contact)
462
sysLocation     = $(location)
463
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
464

    
465
snmpEnableAuthenTraps = 2
466

    
467
EOD;
468

    
469
		if (is_array( $config['snmpd']['modules'] )) {
470
		    if(isset($config['snmpd']['modules']['mibii'])) {
471
			$snmpdconf .= <<<EOD
472
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
473

    
474
EOD;
475
		    }
476

    
477
		    if(isset($config['snmpd']['modules']['netgraph'])) {
478
			$snmpdconf .= <<<EOD
479
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
480
%netgraph
481
begemotNgControlNodeName = "snmpd"
482

    
483
EOD;
484
		    }
485

    
486
		    if(isset($config['snmpd']['modules']['pf'])) {
487
			$snmpdconf .= <<<EOD
488
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
489
# config must end with blank line
490

    
491

    
492
EOD;
493
		    }
494
		}
495

    
496
		fwrite($fd, $snmpdconf);
497
		fclose($fd);
498

    
499
		/* run bsnmpd */
500
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
501
			" -p {$g['varrun_path']}/snmpd.pid");		  
502
//		mwexec("/usr/local/sbin/snmpd -c {$g['varetc_path']}/snmpd.conf" .
503
//			" -P {$g['varrun_path']}/snmpd.pid");
504

    
505
		if ($g['booting'])
506
			echo "done.\n";
507
	}
508

    
509
	return 0;
510
}
511

    
512
function services_proxyarp_configure() {
513
	global $config, $g;
514

    
515
	/* kill any running choparp */
516
	killbyname("choparp");
517

    
518
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
519
		$paa = array();
520

    
521
		/* group by interface */
522
		foreach ($config['virtualip']['vip'] as $vipent) {
523
			if ($vipent['mode'] === "proxyarp") {
524
				if ($vipent['interface'])
525
					$if = $vipent['interface'];
526
				else
527
					$if = "wan";
528

    
529
				if (!is_array($paa[$if]))
530
					$paa[$if] = array();
531

    
532
				$paa[$if][] = $vipent;
533
			}
534
		}
535

    
536
		if (count($paa))
537
		foreach ($paa as $paif => $paents) {
538
			if ($paif == "wan" && !(is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
539
                                       ($config['interfaces']['wan']['ipaddr'] == "dhcp") ||
540
                                       ($config['interfaces']['wan']['ipaddr'] == "bigpond")))
541
                               continue;
542

    
543
			$args = $config['interfaces'][$paif]['if'] . " auto";
544

    
545
			foreach ($paents as $paent) {
546

    
547
				if (isset($paent['subnet']))
548
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
549
				else if (isset($paent['range']))
550
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
551
						$paent['range']['to']);
552
			}
553

    
554
			mwexec_bg("/usr/local/sbin/choparp " . $args);
555
		}
556
	}
557
}
558

    
559
function services_dnsupdate_process() {
560
	global $config, $g;
561
	
562
	/* Dynamic DNS updating active? */
563
	if (isset($config['dnsupdate']['enable'])) {
564
		
565
		$wanip = get_current_wan_address();
566
		if ($wanip) {
567
			
568
			$keyname = $config['dnsupdate']['keyname'];
569
			/* trailing dot */
570
			if (substr($keyname, -1) != ".")
571
				$keyname .= ".";
572
			
573
			$hostname = $config['dnsupdate']['host'];
574
			/* trailing dot */
575
			if (substr($hostname, -1) != ".")
576
				$hostname .= ".";
577
			
578
			/* write private key file
579
			   this is dumb - public and private keys are the same for HMAC-MD5,
580
			   but nsupdate insists on having both */
581
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.private", "w");
582
			$privkey .= <<<EOD
583
Private-key-format: v1.2
584
Algorithm: 157 (HMAC)
585
Key: {$config['dnsupdate']['keydata']}
586

    
587
EOD;
588
			fwrite($fd, $privkey);
589
			fclose($fd);
590
			
591
			/* write public key file */
592
			if ($config['dnsupdate']['keytype'] == "zone") {
593
				$flags = 257;
594
				$proto = 3;
595
			} else if ($config['dnsupdate']['keytype'] == "host") {
596
				$flags = 513;
597
				$proto = 3;
598
			} else if ($config['dnsupdate']['keytype'] == "user") {
599
				$flags = 0;
600
				$proto = 2;
601
			}
602
			
603
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.key", "w");
604
			fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$config['dnsupdate']['keydata']}\n");
605
			fclose($fd);
606
			
607
			/* generate update instructions */
608
			$upinst =  "update delete {$config['dnsupdate']['host']} A\n";
609
			$upinst .= "update add {$config['dnsupdate']['host']} {$config['dnsupdate']['ttl']} A {$wanip}\n";
610
			$upinst .= "\n";	/* mind that trailing newline! */
611
			
612
			$fd = fopen("{$g['varetc_path']}/nsupdatecmds", "w");
613
			fwrite($fd, $upinst);
614
			fclose($fd);
615
			
616
			/* invoke nsupdate */
617
			$cmd = "/usr/sbin/nsupdate -k {$g['varetc_path']}:{$keyname}";
618
			if (isset($config['dnsupdate']['usetcp']))
619
				$cmd .= " -v";
620
			$cmd .= " {$g['varetc_path']}/nsupdatecmds";
621
			
622
			mwexec_bg($cmd);
623
		}
624
	}
625
	
626
	return 0;
627
}
628

    
629
?>
(15-15/22)