Project

General

Profile

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

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

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

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

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

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

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

    
34
function services_dhcpd_configure() {
35
	global $config, $g;
36

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

    
40
	$syscfg = $config['system'];
41
	$dhcpdcfg = $config['dhcpd'];
42

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

    
53
	if (!$dhcpdenable)
54
		return 0;
55

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

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

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

    
76
EOD;
77

    
78
	$dhcpdifs = array();
79
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
80

    
81
		$ifcfg = $config['interfaces'][$dhcpif];
82

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

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

    
91
		$dnscfg = "";
92

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

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

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

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

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

    
121
EOD;
122

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

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

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

    
138
		$dhcpdconf .= <<<EOD
139
}
140

    
141
EOD;
142

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

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

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

    
156
				$dhcpdconf .= "}\n";
157
				$i++;
158
			}
159
		}
160

    
161
		$dhcpdifs[] = $ifcfg['if'];
162
	}
163

    
164
	fwrite($fd, $dhcpdconf);
165
	fclose($fd);
166

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

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

    
174
	if (!$g['booting']) {
175
		filter_configure();
176
	} else
177
		echo "done\n";
178

    
179
	return 0;
180
}
181

    
182
function services_dhcrelay_configure() {
183
	global $config, $g;
184

    
185
	/* kill any running dhcrelay */
186
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
187

    
188
	$dhcrelaycfg = $config['dhcrelay'];
189

    
190
	/* DHCPRelay enabled on any interfaces? */
191
	$dhcrelayenable = false;
192
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
193
		if (isset($dhcrelayifconf['enable']) &&
194
			(($dhcrelayif == "lan") ||
195
			(isset($config['interfaces'][$dhcrelayif]['enable']) &&
196
			$config['interfaces'][$dhcrelayif]['if'] && (!$config['interfaces'][$dhcrelayif]['bridge']))))
197
			$dhcrelayenable = true;
198
	}
199

    
200
	if (!$dhcrelayenable)
201
		return 0;
202

    
203
	if ($g['booting'])
204
		echo "Starting DHCP relay service... ";
205
	else
206
		sleep(1);
207

    
208
	$dhcrelayifs = array();
209
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
210

    
211
		$ifcfg = $config['interfaces'][$dhcrelayif];
212

    
213
		if (!isset($dhcrelayifconf['enable']) ||
214
			(($dhcrelayif != "lan") &&
215
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
216
			continue;
217

    
218
		$dhcrelayifs[] = $ifcfg['if'];
219
	}
220

    
221
	/* In order for the relay to work, it needs to be active on the
222
	   interface in which the destination server sits */
223
	foreach ($config['interfaces'] as $ifname) {
224
		$subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
225
		if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
226
			$destif = $ifname['if'];
227
	}
228

    
229
	if (!isset($destif))
230
		$destif = $config['interfaces']['wan']['if'];
231

    
232
	$dhcrelayifs[] = $destif;
233
	$dhcrelayifs = array_unique($dhcrelayifs);
234

    
235
	/* fire up dhcrelay */
236
	$cmd = "/usr/local/sbin/dhcrelay -i " .  join(" -i ", $dhcrelayifs);
237

    
238
	if (isset($dhcrelaycfg['agentoption']))
239
		$cmd .=  " -a -m replace";
240

    
241
	$cmd .= " {$dhcrelaycfg['server']}";
242
	mwexec($cmd);
243

    
244
	if (!$g['booting']) {
245
		filter_configure();
246
	} else
247
		echo "done\n";
248

    
249
	return 0;
250
}
251

    
252
function services_dyndns_reset() {
253
	global $config, $g;
254

    
255
	if (file_exists("{$g['vardb_path']}/ez-ipupdate.cache")) {
256
		unlink("{$g['vardb_path']}/ez-ipupdate.cache");
257
	}
258

    
259
	if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
260
		conf_mount_rw();
261
		unlink("{$g['conf_path']}/ez-ipupdate.cache");
262
		conf_mount_ro();
263
	}
264

    
265
	return 0;
266
}
267

    
268
function services_dyndns_configure() {
269
	global $config, $g;
270

    
271
	/* kill any running ez-ipupdate */
272
	/* ez-ipupdate needs SIGQUIT instead of SIGTERM */
273
	sigkillbypid("{$g['varrun_path']}/ez-ipupdate.pid", "QUIT");
274

    
275
	$dyndnscfg = $config['dyndns'];
276
	$wancfg = $config['interfaces']['wan'];
277

    
278
	if (isset($dyndnscfg['enable'])) {
279

    
280
		if ($g['booting'])
281
			echo "Starting DynDNS client... ";
282
		else
283
			sleep(1);
284

    
285
		/* determine WAN interface name */
286
		$wanif = get_real_wan_interface();
287

    
288
		/* write ez-ipupdate.conf */
289
		$fd = fopen("{$g['varetc_path']}/ez-ipupdate.conf", "w");
290
		if (!$fd) {
291
			printf("Error: cannot open ez-ipupdate.conf in services_dyndns_configure().\n");
292
			return 1;
293
		}
294

    
295
		$ezipupdateconf = <<<EOD
296
service-type={$dyndnscfg['type']}
297
user={$dyndnscfg['username']}:{$dyndnscfg['password']}
298
host={$dyndnscfg['host']}
299
interface=$wanif
300
max-interval=2073600
301
pid-file={$g['varrun_path']}/ez-ipupdate.pid
302
cache-file={$g['vardb_path']}/ez-ipupdate.cache
303
execute=/etc/rc.dyndns.storecache
304
daemon
305

    
306
EOD;
307

    
308
		/* enable MX? */
309
		if ($dyndnscfg['mx']) {
310
			$ezipupdateconf .= "mx={$dyndnscfg['mx']}\n";
311
		}
312

    
313
		/* enable wildcards? */
314
		if (isset($dyndnscfg['wildcard'])) {
315
			$ezipupdateconf .= "wildcard\n";
316
		}
317

    
318
		fwrite($fd, $ezipupdateconf);
319
		fclose($fd);
320

    
321
		/* if we're booting, copy the cache file from /conf */
322
		if ($g['booting']) {
323
			if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
324
				copy("{$g['conf_path']}/ez-ipupdate.cache", "{$g['vardb_path']}/ez-ipupdate.cache");
325
			}
326
		}
327

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

    
331
		if ($g['booting'])
332
			echo "done\n";
333
	}
334

    
335
	return 0;
336
}
337

    
338
function services_dnsmasq_configure() {
339
	global $config, $g;
340

    
341
	/* kill any running dnsmasq */
342
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
343

    
344
	if (isset($config['dnsmasq']['enable'])) {
345

    
346
		if ($g['booting'])
347
			echo "Starting DNS forwarder... ";
348
		else
349
			sleep(1);
350

    
351
		/* generate hosts file */
352
		system_hosts_generate();
353

    
354
		$args = "";
355

    
356
		if (isset($config['dnsmasq']['regdhcp'])) {
357

    
358
			$args .= " -l {$g['vardb_path']}/dhcpd.leases" .
359
				" -s {$config['system']['domain']}";
360
		}
361

    
362
		/* run dnsmasq */
363
		mwexec("/usr/local/sbin/dnsmasq {$args}");
364

    
365
		if ($g['booting'])
366
			echo "done\n";
367
	}
368

    
369
	if (!$g['booting']) {
370
		services_dhcpd_configure();
371
	}
372

    
373
	return 0;
374
}
375

    
376
function services_snmpd_configure() {
377
	global $config, $g;
378

    
379
	/* kill any running snmpd */
380
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
381

    
382
	if (isset($config['snmpd']['enable'])) {
383

    
384
		if ($g['booting'])
385
			echo "Starting SNMP agent... ";
386

    
387
		/* generate snmpd.conf */
388
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
389
		if (!$fd) {
390
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
391
			return 1;
392
		}
393

    
394
		$snmpdconf = <<<EOD
395
syslocation "{$config['snmpd']['syslocation']}"
396
syscontact "{$config['snmpd']['syscontact']}"
397
rocommunity "{$config['snmpd']['rocommunity']}"
398

    
399
EOD;
400

    
401
		fwrite($fd, $snmpdconf);
402
		fclose($fd);
403

    
404
		/* run snmpd */
405
		mwexec("/usr/local/sbin/snmpd -c {$g['varetc_path']}/snmpd.conf" .
406
			" -P {$g['varrun_path']}/snmpd.pid");
407

    
408
		if ($g['booting'])
409
			echo "done\n";
410
	}
411

    
412
	return 0;
413
}
414

    
415
function services_proxyarp_configure() {
416
	global $config, $g;
417

    
418
	/* kill any running choparp */
419
	killbyname("choparp");
420

    
421
	if (is_array($config['proxyarp']) && count($config['proxyarp'])) {
422

    
423
		$paa = array();
424

    
425
		/* group by interface */
426
		foreach ($config['proxyarp']['proxyarpnet'] as $paent) {
427
                       if ($paent['interface'])
428
                               $if = $paent['interface'];
429
                       else
430
                               $if = "wan";
431

    
432
                       if (!is_array($paa[$if]))
433
                               $paa[$if] = array();
434

    
435
                       $paa[$if][] = $paent;
436
               }
437

    
438
               foreach ($paa as $paif => $paents) {
439
                       if ($paif == "wan" && !(is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
440
                                       ($config['interfaces']['wan']['ipaddr'] == "dhcp") ||
441
                                       ($config['interfaces']['wan']['ipaddr'] == "bigpond")))
442
                               continue;
443

    
444
                       $args = $config['interfaces'][$paif]['if'] . " auto";
445

    
446
                       foreach ($paents as $paent) {
447

    
448
			if (isset($paent['network']))
449
				$args .= " " . escapeshellarg($paent['network']);
450
			else if (isset($paent['range']))
451
				$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
452
					$paent['range']['to']);
453
		}
454

    
455
		mwexec_bg("/usr/local/sbin/choparp " . $args);
456
	}
457
	}
458
}
459

    
460
function services_dnsupdate_process() {
461
	global $config, $g;
462
	
463
	/* Dynamic DNS updating active? */
464
	if (isset($config['dnsupdate']['enable'])) {
465
		
466
		$wanip = get_current_wan_address();
467
		if ($wanip) {
468
			
469
			$keyname = $config['dnsupdate']['keyname'];
470
			/* trailing dot */
471
			if (substr($keyname, -1) != ".")
472
				$keyname .= ".";
473
			
474
			$hostname = $config['dnsupdate']['host'];
475
			/* trailing dot */
476
			if (substr($hostname, -1) != ".")
477
				$hostname .= ".";
478
			
479
			/* write private key file
480
			   this is dumb - public and private keys are the same for HMAC-MD5,
481
			   but nsupdate insists on having both */
482
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.private", "w");
483
			$privkey .= <<<EOD
484
Private-key-format: v1.2
485
Algorithm: 157 (HMAC)
486
Key: {$config['dnsupdate']['keydata']}
487

    
488
EOD;
489
			fwrite($fd, $privkey);
490
			fclose($fd);
491
			
492
			/* write public key file */
493
			if ($config['dnsupdate']['keytype'] == "zone") {
494
				$flags = 257;
495
				$proto = 3;
496
			} else if ($config['dnsupdate']['keytype'] == "host") {
497
				$flags = 513;
498
				$proto = 3;
499
			} else if ($config['dnsupdate']['keytype'] == "user") {
500
				$flags = 0;
501
				$proto = 2;
502
			}
503
			
504
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.key", "w");
505
			fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$config['dnsupdate']['keydata']}\n");
506
			fclose($fd);
507
			
508
			/* generate update instructions */
509
			$upinst =  "update delete {$config['dnsupdate']['host']} A\n";
510
			$upinst .= "update add {$config['dnsupdate']['host']} {$config['dnsupdate']['ttl']} A {$wanip}\n";
511
			$upinst .= "\n";	/* mind that trailing newline! */
512
			
513
			$fd = fopen("{$g['varetc_path']}/nsupdatecmds", "w");
514
			fwrite($fd, $upinst);
515
			fclose($fd);
516
			
517
			/* invoke nsupdate */
518
			$cmd = "/usr/sbin/nsupdate -k {$g['varetc_path']}:{$keyname}";
519
			if (isset($config['dnsupdate']['usetcp']))
520
				$cmd .= " -v";
521
			$cmd .= " {$g['varetc_path']}/nsupdatecmds";
522
			
523
			mwexec_bg($cmd);
524
		}
525
	}
526
	
527
	return 0;
528
}
529

    
530
?>
(10-10/14)