Project

General

Profile

Download (14.2 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 interfaces_staticarp_configure($if) {
183
        global $config, $g;
184
        
185
        $ifcfg = $config['interfaces'][$if];
186

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

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

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

    
204
        return 0;
205
}
206

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
269
	if (!$g['booting']) {
270
		filter_configure();
271
	} else
272
		echo "done\n";
273

    
274
	return 0;
275
}
276

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

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

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

    
290
	return 0;
291
}
292

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

    
296
	/* kill any running ez-ipupdate */
297
	/* ez-ipupdate needs SIGQUIT instead of SIGTERM */
298
	sigkillbypid("{$g['varrun_path']}/ez-ipupdate.pid", "QUIT");
299

    
300
	$dyndnscfg = $config['dyndns'];
301
	$wancfg = $config['interfaces']['wan'];
302

    
303
	if (isset($dyndnscfg['enable'])) {
304

    
305
		if ($g['booting'])
306
			echo "Starting DynDNS client... ";
307
		else
308
			sleep(1);
309

    
310
		/* determine WAN interface name */
311
		$wanif = get_real_wan_interface();
312

    
313
		/* write ez-ipupdate.conf */
314
		$fd = fopen("{$g['varetc_path']}/ez-ipupdate.conf", "w");
315
		if (!$fd) {
316
			printf("Error: cannot open ez-ipupdate.conf in services_dyndns_configure().\n");
317
			return 1;
318
		}
319

    
320
		$ezipupdateconf = <<<EOD
321
service-type={$dyndnscfg['type']}
322
user={$dyndnscfg['username']}:{$dyndnscfg['password']}
323
host={$dyndnscfg['host']}
324
interface=$wanif
325
max-interval=2073600
326
pid-file={$g['varrun_path']}/ez-ipupdate.pid
327
cache-file={$g['vardb_path']}/ez-ipupdate.cache
328
execute=/etc/rc.dyndns.storecache
329
daemon
330

    
331
EOD;
332

    
333
		/* enable MX? */
334
		if ($dyndnscfg['mx']) {
335
			$ezipupdateconf .= "mx={$dyndnscfg['mx']}\n";
336
		}
337

    
338
		/* enable wildcards? */
339
		if (isset($dyndnscfg['wildcard'])) {
340
			$ezipupdateconf .= "wildcard\n";
341
		}
342

    
343
		fwrite($fd, $ezipupdateconf);
344
		fclose($fd);
345

    
346
		/* if we're booting, copy the cache file from /conf */
347
		if ($g['booting']) {
348
			if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
349
				copy("{$g['conf_path']}/ez-ipupdate.cache", "{$g['vardb_path']}/ez-ipupdate.cache");
350
			}
351
		}
352

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

    
356
		if ($g['booting'])
357
			echo "done\n";
358
	}
359

    
360
	return 0;
361
}
362

    
363
function services_dnsmasq_configure() {
364
	global $config, $g;
365

    
366
	/* kill any running dnsmasq */
367
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
368

    
369
	if (isset($config['dnsmasq']['enable'])) {
370

    
371
		if ($g['booting'])
372
			echo "Starting DNS forwarder... ";
373
		else
374
			sleep(1);
375

    
376
		/* generate hosts file */
377
		system_hosts_generate();
378

    
379
		$args = "";
380

    
381
		if (isset($config['dnsmasq']['regdhcp'])) {
382

    
383
			$args .= " -l {$g['vardb_path']}/dhcpd.leases" .
384
				" -s {$config['system']['domain']}";
385
		}
386

    
387
		/* run dnsmasq */
388
		mwexec("/usr/local/sbin/dnsmasq {$args}");
389

    
390
		if ($g['booting'])
391
			echo "done\n";
392
	}
393

    
394
	if (!$g['booting']) {
395
		services_dhcpd_configure();
396
	}
397

    
398
	return 0;
399
}
400

    
401
function services_snmpd_configure() {
402
	global $config, $g;
403

    
404
	/* kill any running snmpd */
405
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
406

    
407
	if (isset($config['snmpd']['enable'])) {
408

    
409
		if ($g['booting'])
410
			echo "Starting SNMP agent... ";
411

    
412
		/* generate snmpd.conf */
413
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
414
		if (!$fd) {
415
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
416
			return 1;
417
		}
418

    
419
		$snmpdconf = <<<EOD
420
syslocation "{$config['snmpd']['syslocation']}"
421
syscontact "{$config['snmpd']['syscontact']}"
422
rocommunity "{$config['snmpd']['rocommunity']}"
423

    
424
EOD;
425

    
426
		fwrite($fd, $snmpdconf);
427
		fclose($fd);
428

    
429
		/* run snmpd */
430
		mwexec("/usr/local/sbin/snmpd -c {$g['varetc_path']}/snmpd.conf" .
431
			" -P {$g['varrun_path']}/snmpd.pid");
432

    
433
		if ($g['booting'])
434
			echo "done\n";
435
	}
436

    
437
	return 0;
438
}
439

    
440
function services_proxyarp_configure() {
441
	global $config, $g;
442

    
443
	/* kill any running choparp */
444
	killbyname("choparp");
445

    
446
	if (is_array($config['proxyarp']) && count($config['proxyarp'])) {
447

    
448
		$paa = array();
449

    
450
		/* group by interface */
451
		foreach ($config['proxyarp']['proxyarpnet'] as $paent) {
452
			if ($paent['interface'])
453
				$if = $paent['interface'];
454
			else
455
				$if = "wan";
456

    
457
			if (!is_array($paa[$if]))
458
				$paa[$if] = array();
459

    
460
			$paa[$if][] = $paent;
461
		}
462

    
463
		foreach ($paa as $paif => $paents) {
464
			if ($paif == "wan" && !(is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
465
                                       ($config['interfaces']['wan']['ipaddr'] == "dhcp") ||
466
                                       ($config['interfaces']['wan']['ipaddr'] == "bigpond")))
467
                               continue;
468

    
469
			$args = $config['interfaces'][$paif]['if'] . " auto";
470

    
471
			foreach ($paents as $paent) {
472

    
473
				if (isset($paent['network']))
474
					$args .= " " . escapeshellarg($paent['network']);
475
				else if (isset($paent['range']))
476
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
477
						$paent['range']['to']);
478
			}
479

    
480
			mwexec_bg("/usr/local/sbin/choparp " . $args);
481
		}
482
	}
483
}
484

    
485
function services_dnsupdate_process() {
486
	global $config, $g;
487
	
488
	/* Dynamic DNS updating active? */
489
	if (isset($config['dnsupdate']['enable'])) {
490
		
491
		$wanip = get_current_wan_address();
492
		if ($wanip) {
493
			
494
			$keyname = $config['dnsupdate']['keyname'];
495
			/* trailing dot */
496
			if (substr($keyname, -1) != ".")
497
				$keyname .= ".";
498
			
499
			$hostname = $config['dnsupdate']['host'];
500
			/* trailing dot */
501
			if (substr($hostname, -1) != ".")
502
				$hostname .= ".";
503
			
504
			/* write private key file
505
			   this is dumb - public and private keys are the same for HMAC-MD5,
506
			   but nsupdate insists on having both */
507
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.private", "w");
508
			$privkey .= <<<EOD
509
Private-key-format: v1.2
510
Algorithm: 157 (HMAC)
511
Key: {$config['dnsupdate']['keydata']}
512

    
513
EOD;
514
			fwrite($fd, $privkey);
515
			fclose($fd);
516
			
517
			/* write public key file */
518
			if ($config['dnsupdate']['keytype'] == "zone") {
519
				$flags = 257;
520
				$proto = 3;
521
			} else if ($config['dnsupdate']['keytype'] == "host") {
522
				$flags = 513;
523
				$proto = 3;
524
			} else if ($config['dnsupdate']['keytype'] == "user") {
525
				$flags = 0;
526
				$proto = 2;
527
			}
528
			
529
			$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.key", "w");
530
			fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$config['dnsupdate']['keydata']}\n");
531
			fclose($fd);
532
			
533
			/* generate update instructions */
534
			$upinst =  "update delete {$config['dnsupdate']['host']} A\n";
535
			$upinst .= "update add {$config['dnsupdate']['host']} {$config['dnsupdate']['ttl']} A {$wanip}\n";
536
			$upinst .= "\n";	/* mind that trailing newline! */
537
			
538
			$fd = fopen("{$g['varetc_path']}/nsupdatecmds", "w");
539
			fwrite($fd, $upinst);
540
			fclose($fd);
541
			
542
			/* invoke nsupdate */
543
			$cmd = "/usr/sbin/nsupdate -k {$g['varetc_path']}:{$keyname}";
544
			if (isset($config['dnsupdate']['usetcp']))
545
				$cmd .= " -v";
546
			$cmd .= " {$g['varetc_path']}/nsupdatecmds";
547
			
548
			mwexec_bg($cmd);
549
		}
550
	}
551
	
552
	return 0;
553
}
554

    
555
?>
(10-10/14)