Project

General

Profile

Download (33.5 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
	
38
	if($g['services_dhcp_server_enable'] == false) 
39
		return;
40

    
41
	if(isset($config['system']['developerspew'])) {
42
		$mt = microtime();
43
		echo "services_dhcpd_configure($if) being called $mt\n";
44
	}
45
	
46
	/* kill any running dhcpd */
47
	if(is_process_running("dhcpd"))
48
		mwexec("killall dhcpd", true);
49

    
50
	/* DHCP enabled on any interfaces? */
51
	if (!is_dhcp_server_enabled())
52
		return 0;
53

    
54
	/* if OLSRD is enabled, allow WAN to house DHCP. */
55
	if($config['installedpackages']['olsrd'])
56
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
57
				if($olsrd['enable'])
58
					$is_olsr_enabled = true;
59

    
60
	/* configure DHCPD chroot */
61
	$fd = fopen("/tmp/dhcpd.sh","w");
62
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
63
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
64
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
65
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
66
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
67
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
68
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
69
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
70
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
71
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
72
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
73
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
74
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
75
	if(!trim($status))
76
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
77
	fclose($fd);
78
	mwexec("/bin/sh /tmp/dhcpd.sh");
79

    
80
	$syscfg = $config['system'];
81
	$dhcpdcfg = $config['dhcpd'];
82
	$Iflist = get_configured_interface_list();
83
		
84
	if ($g['booting'])
85
		echo "Starting DHCP service...";
86
	else
87
		sleep(1);
88

    
89
	/* write dhcpd.conf */
90
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
91
	if (!$fd) {
92
		printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
93
		return 1;
94
	}
95

    
96

    
97

    
98
	$dhcpdconf = <<<EOD
99
	
100
option domain-name "{$syscfg['domain']}";
101
option ldap-server code 95 = text;
102
option domain-search-list code 119 = text;
103
default-lease-time 7200;
104
max-lease-time 86400;
105
log-facility local7;
106
ddns-update-style none;
107
one-lease-per-client true;
108
deny duplicates;
109
ping-check true;
110

    
111
EOD;
112

    
113
	if(isset($dhcpifconf['alwaysbroadcast'])) 
114
		$dhcpdconf .= "always-broadcast on\n";
115

    
116
	$dhcpdifs = array();
117

    
118
	/*    loop through and deterimine if we need to setup
119
	 *    failover peer "bleh" entries
120
	 */
121
	$dhcpnum = 0;
122
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
123

    
124
		if (!isset($dhcpifconf['enable']))
125
			continue;
126

    
127
		if(!isset($dhcpifconf['disableauthoritative']))
128
			$dhcpdconf .= "authoritative;\n";
129

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

    
176
EOPP;
177
		$dhcpnum++;
178
		}
179
	}
180

    
181
	$dhcpnum = 0;
182

    
183
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
184

    
185
		$ifcfg = $config['interfaces'][$dhcpif];
186

    
187
		if (!isset($dhcpifconf['enable']) || !isset($Iflist[$dhcpif]))
188
			continue;
189
		$ifcfgip = get_interface_ip($dhcpif);
190
		$ifcfgsn = get_interface_subnet($dhcpif);
191
		$subnet = gen_subnet($ifcfgip, $ifcfgsn);
192
		$subnetmask = gen_subnet_mask($ifcfgsn);
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
		
204
    		if($dhcpifconf['domainsearchlist'] <> "") {
205
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
206
    		}
207

    
208
		if (isset($dhcpifconf['ddnsupdate'])) {
209
			if($dhcpifconf['ddnsdomain'] <> "") {
210
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
211
			}
212
			$dnscfg .= "	ddns-update-style interim;\n";
213
		}
214

    
215
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
216
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
217
		} else if (isset($config['dnsmasq']['enable'])) {
218
			$dnscfg .= "	option domain-name-servers {$ifcfgip};";
219
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
220
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
221
		}
222

    
223
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
224
		$dhcpdconf .= "	pool {\n";
225

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

    
234
		if($dhcpifconf['failover_peerip'] <> "")
235
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
236

    
237
		if (isset($dhcpifconf['denyunknown']))
238
		   $dhcpdconf .= "		deny unknown clients;\n";
239

    
240
		if ($dhcpifconf['gateway'])
241
			$routers = $dhcpifconf['gateway'];
242
		else
243
			$routers = $ifcfgip;
244

    
245
		if($dhcpifconf['failover_peerip'] <> "") {
246
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
247
			$dhcpnum++;
248
		}
249

    
250
		$dhcpdconf .= <<<EOD
251
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
252
	}
253
	option routers {$routers};
254
$dnscfg
255

    
256
EOD;
257
    
258
    		if ($dhcpifconf['defaultleasetime'])
259
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
260
		if ($dhcpifconf['maxleasetime'])
261
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
262

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

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

    
271
		if ($dhcpifconf['tftp'] <> "")
272
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
273

    
274
    if ($dhcpifconf['ldap'] <> "")
275
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
276

    
277
		if(isset($dhcpifconf['netboot'])) {
278
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
279
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
280
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
281
			}
282
			if ($dhcpifconf['rootpath'] <> "") {
283
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
284
      }
285
		}
286
		
287
		$dhcpdconf .= <<<EOD
288
}
289

    
290
EOD;
291

    
292
		/* add static mappings */
293
		if (is_array($dhcpifconf['staticmap'])) {
294

    
295
			$i = 0;
296
			foreach ($dhcpifconf['staticmap'] as $sm) {
297
				$dhcpdconf .= <<<EOD
298
host s_{$dhcpif}_{$i} {
299
	hardware ethernet {$sm['mac']};
300

    
301
EOD;
302
				if ($sm['ipaddr'])
303
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
304

    
305
				if ($sm['hostname'])
306
					$dhcpdconf .= "	option host-name {$sm['hostname']};\n";
307

    
308
				$dhcpdconf .= "}\n";
309
				$i++;
310
			}
311
		}
312

    
313
		$dhcpdifs[] = get_real_interface($dhcpif);
314
	}
315

    
316
	fwrite($fd, $dhcpdconf);
317
	fclose($fd);
318

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

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

    
326
	if ($g['booting']) {
327
		print "done.\n";
328
	}
329

    
330
	return 0;
331
}
332

    
333
function services_igmpproxy_configure() {
334
        global $config, $g;
335

    
336
        $iflist = get_configured_interface_list();
337

    
338
        /* kill any running igmpproxy */
339
        killbyname("igmpproxy");
340

    
341
	if (!is_array($config['igmpproxy']['igmpentry']))
342
		return 1;
343

    
344
        $igmpconf = <<<EOD
345

    
346
##------------------------------------------------------
347
## Enable Quickleave mode (Sends Leave instantly)
348
##------------------------------------------------------
349
quickleave
350

    
351
EOD;
352

    
353
        foreach ($config['igmpproxy']['igmpentry'] as $igmpcf) {
354
                unset($iflist[$igmpcf['ifname']]);
355
                $realif = get_real_interface($igmpcf['ifname']);
356
                if (empty($igmpcf['threshold']))
357
                        $threshld = 1;
358
                else
359
                        $threshld = $igmpcf['threshold'];
360
                $igmpconf .= "phyint {$realif} {$igmpcf['type']} ratelimit 0 threshold {$threshld}\n";
361

    
362
                if ($igmpcf['address'] <> "") {
363
                        $item = explode(" ", $igmpcf['address']);
364
                        foreach($item as $iww)
365
                                $igmpconf .= "altnet {$iww}\n";
366
                }
367
                $igmpconf .= "\n";
368
        }
369
        foreach ($iflist as $ifn) {
370
                $realif = get_real_interface($ifn);
371
                $igmpconf .= "phyint {$realif} disabled\n";
372
        }
373

    
374
        $igmpfl = fopen($g['tmp_path'] . "/igmpproxy.conf", "w");
375
        if (!$igmpfl) {
376
                log_error("Could not write Igmpproxy configuration file!");
377
                return;
378
        }
379
        fwrite($igmpfl, $igmpconf);
380
        fclose($igmpfl);
381

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

    
385
        return 0;
386
}
387

    
388
function interfaces_staticarp_configure($if) {
389
	global $config, $g;
390
	if(isset($config['system']['developerspew'])) {
391
		$mt = microtime();
392
		echo "interfaces_staticarp_configure($if) being called $mt\n";
393
	}
394

    
395
        $ifcfg = $config['interfaces'][$if];
396

    
397
        /* Enable staticarp, if enabled */
398
        if(isset($config['dhcpd'][$if]['staticarp'])) {
399
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
400
                mwexec("/usr/sbin/arp -ad > /dev/null 2>&1 ");
401
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
402

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

    
406
                        }
407

    
408
                }
409
        } else {
410
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
411
                mwexec("/usr/sbin/arp -da > /dev/null 2>&1 ");
412
        }
413

    
414
        return 0;
415
}
416

    
417
function services_dhcrelay_configure() {
418
	global $config, $g;
419
	if(isset($config['system']['developerspew'])) {
420
		$mt = microtime();
421
		echo "services_dhcrelay_configure() being called $mt\n";
422
	}
423

    
424
	/* kill any running dhcrelay */
425
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
426

    
427
	$dhcrelaycfg = $config['dhcrelay'];
428

    
429
	/* DHCPRelay enabled on any interfaces? */
430
	$dhcrelayenable = false;
431
	if(is_array($dhcrelaycfg)) {
432
		foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
433
			if (isset($dhcrelayifconf['enable']) &&
434
				(($dhcrelayif == "lan") ||
435
				(isset($config['interfaces'][$dhcrelayif]['enable']) &&
436
				$config['interfaces'][$dhcrelayif]['if'] && (!link_interface_to_bridge($dhcrelayif)))))
437
				$dhcrelayenable = true;
438
		}
439
	}
440

    
441
	if (!$dhcrelayenable)
442
		return 0;
443

    
444
	if ($g['booting'])
445
		echo "Starting DHCP relay service...";
446
	else
447
		sleep(1);
448

    
449
	$dhcrelayifs = array();
450
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
451

    
452
		$ifcfg = $config['interfaces'][$dhcrelayif];
453

    
454
		if (!isset($dhcrelayifconf['enable']) ||
455
			(($dhcrelayif != "lan") &&
456
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || 
457
			link_interface_to_bridge($dhcrelayif))))
458
			continue;
459

    
460
		$dhcrelayifs[] = get_real_interface($dhcprelayif);
461
	}
462

    
463
	/* In order for the relay to work, it needs to be active on the
464
	   interface in which the destination server sits */
465
	$dhrelayifs = get_configured_interface_list();
466
	foreach ($dhrelayifs as $ifname) {
467
		$subnet = get_interface_ip($ifname) . "/" . get_interface_subnet($ifname);
468
		if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
469
			$destif = $ifname['if'];
470
	}
471

    
472
	if (!isset($destif))
473
		$destif = $config['interfaces']['wan']['if'];
474

    
475
	$dhcrelayifs[] = $destif;
476
	$dhcrelayifs = array_unique($dhcrelayifs);
477

    
478
	/* fire up dhcrelay */
479
	$cmd = "/usr/local/sbin/dhcrelay -i " .  join(" -i ", $dhcrelayifs);
480

    
481
	if (isset($dhcrelaycfg['agentoption']))
482
		$cmd .=  " -a -m replace";
483

    
484
	$cmd .= " {$dhcrelaycfg['server']}";
485
	mwexec($cmd);
486

    
487
	if (!$g['booting']) {
488
		/* set the reload filter dity flag */
489
		filter_configure();
490
	}
491

    
492
	return 0;
493
}
494

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

    
502
	$dyndnscfg = $config['dyndnses']['dyndns'];
503

    
504
        if (is_array($dyndnscfg)) {
505
                foreach ($dyndnscfg as $dyndns) {
506
                        if (!isset($dyndns['enable']))
507
                                continue;
508
			if ($dyndns['interface'] != $interface)
509
				continue;
510

    
511
                        services_dyndns_configure_client($dyndns);
512

    
513
                        sleep(1);
514
                }
515

    
516
        }
517

    
518
	return 0;
519
}
520

    
521
function services_dyndns_configure_client($conf) {
522

    
523
	/* load up the dyndns.class */
524
	require_once("dyndns.class");
525

    
526
	log_error("DynDns: Running updatedns()");
527

    
528
	$dns = new updatedns($dnsService = $conf['type'],
529
		$dnsHost = $conf['host'],
530
		$dnsUser = $conf['username'],
531
		$dnsPass = $conf['password'],
532
		$dnsWilcard = $conf['wildcard'],
533
		$dnsMX = $conf['mx'], $dnsIf = "{$conf['interface']}");
534

    
535
}
536

    
537
function services_dyndns_configure() {
538
	global $config, $g;
539
	if(isset($config['system']['developerspew'])) {
540
		$mt = microtime();
541
		echo "services_dyndns_configure() being called $mt\n";
542
	}
543

    
544
	$dyndnscfg = $config['dyndnses']['dyndns'];
545

    
546
	if (is_array($dyndnscfg)) {
547
		if ($g['booting']) 
548
			echo "Starting DynDNS clients...";
549

    
550
		foreach ($dyndnscfg as $dyndns) {
551
			if (!isset($dyndns['enable']))
552
				continue;
553

    
554
			services_dyndns_configure_client($dyndns);
555

    
556
			sleep(1);
557
		}
558

    
559
		if ($g['booting'])
560
			echo "done.\n";
561
	}
562

    
563
	return 0;
564
}
565

    
566
function services_dnsmasq_configure() {
567
	global $config, $g;
568
	$return = 0;
569
	
570
	if(isset($config['system']['developerspew'])) {
571
		$mt = microtime();
572
		echo "services_dnsmasq_configure() being called $mt\n";
573
	}
574

    
575
	/* kill any running dnsmasq */
576
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
577

    
578
	if (isset($config['dnsmasq']['enable'])) {
579

    
580
		if ($g['booting'])
581
			echo "Starting DNS forwarder...";
582
		else
583
			sleep(1);
584

    
585
		/* generate hosts file */
586
		if(system_hosts_generate()!=0)
587
			$return = 1;
588

    
589
		$args = "";
590

    
591
		if (isset($config['dnsmasq']['regdhcp'])) {
592

    
593
			$args .= " -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases" .
594
				" -s {$config['system']['domain']}";
595
		}
596

    
597
                if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
598
                        foreach($config['dnsmasq']['domainoverrides'] as $override) {
599
                                $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
600
                        }
601
                }
602

    
603
		/* suppose that dnsmasq handles our domain and don't send
604
		requests for our local domain to upstream servers */
605
		//if (!empty($config['system']['domain'])) {
606
		//	$args .= sprintf(' --local=/%s/', $config['system']['domain']);
607
		//}
608

    
609
		/* run dnsmasq */
610
		mwexec("/usr/local/sbin/dnsmasq --cache-size=5000 {$args}");
611

    
612
		if ($g['booting'])
613
			echo "done.\n";
614
	}
615

    
616
	if (!$g['booting']) {
617
		if(services_dhcpd_configure()!=0)
618
			$return = 1;
619
	}
620

    
621
	return $return;
622
}
623

    
624
function services_snmpd_configure() {
625
	global $config, $g;
626
	if(isset($config['system']['developerspew'])) {
627
		$mt = microtime();
628
		echo "services_snmpd_configure() being called $mt\n";
629
	}
630

    
631
	/* kill any running snmpd */
632
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
633
	if(is_process_running("bsnmpd")) 
634
		mwexec("/usr/bin/killall bsnmpd", true);
635

    
636
	if (isset($config['snmpd']['enable'])) {
637

    
638
		if ($g['booting'])
639
			echo "Starting SNMP daemon... ";
640

    
641
		/* generate snmpd.conf */
642
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
643
		if (!$fd) {
644
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
645
			return 1;
646
		}
647

    
648

    
649
		$snmpdconf = <<<EOD
650
location := "{$config['snmpd']['syslocation']}"
651
contact := "{$config['snmpd']['syscontact']}"
652
read := "{$config['snmpd']['rocommunity']}"
653

    
654
EOD;
655

    
656
/* No docs on what write strings do there for disable for now.
657
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
658
		    $snmpdconf .= <<<EOD
659
# write string
660
write := "{$config['snmpd']['rwcommunity']}"
661

    
662
EOD;
663
		}
664
*/
665

    
666

    
667
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
668
		    $snmpdconf .= <<<EOD
669
# SNMP Trap support.
670
traphost := {$config['snmpd']['trapserver']}
671
trapport := {$config['snmpd']['trapserverport']}
672
trap := "{$config['snmpd']['trapstring']}"
673

    
674

    
675
EOD;
676
		}
677

    
678

    
679
		$snmpdconf .= <<<EOD
680
system := 1     # pfSense
681
%snmpd
682
begemotSnmpdDebugDumpPdus       = 2
683
begemotSnmpdDebugSyslogPri      = 7
684
begemotSnmpdCommunityString.0.1 = $(read)
685

    
686
EOD;
687

    
688
/* No docs on what write strings do there for disable for now.
689
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
690
		    $snmpdconf .= <<<EOD
691
begemotSnmpdCommunityString.0.2 = $(write)
692

    
693
EOD;
694
		}
695
*/
696

    
697

    
698
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
699
		    $snmpdconf .= <<<EOD
700
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
701
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
702
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
703

    
704
EOD;
705
		}
706

    
707

    
708
		$snmpdconf .= <<<EOD
709
begemotSnmpdCommunityDisable    = 1
710

    
711
EOD;
712

    
713
		if(isset($config['snmpd']['bindlan'])) {
714
			$bind_to_ip = get_interface_ip("lan");
715
		} else {
716
			$bind_to_ip = "0.0.0.0";
717
		}
718

    
719
		if(is_port( $config['snmpd']['pollport'] )) {
720
		    $snmpdconf .= <<<EOD
721
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
722

    
723
EOD;
724

    
725
		}
726

    
727
		$snmpdconf .= <<<EOD
728
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
729
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
730

    
731
# These are bsnmp macros not php vars.
732
sysContact      = $(contact)
733
sysLocation     = $(location)
734
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
735

    
736
snmpEnableAuthenTraps = 2
737

    
738
EOD;
739

    
740
		if (is_array( $config['snmpd']['modules'] )) {
741
		    if(isset($config['snmpd']['modules']['mibii'])) {
742
			$snmpdconf .= <<<EOD
743
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
744

    
745
EOD;
746
		    }
747

    
748
		    if(isset($config['snmpd']['modules']['netgraph'])) {
749
			$snmpdconf .= <<<EOD
750
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
751
%netgraph
752
begemotNgControlNodeName = "snmpd"
753

    
754
EOD;
755
		    }
756

    
757
		    if(isset($config['snmpd']['modules']['pf'])) {
758
			$snmpdconf .= <<<EOD
759
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
760

    
761
EOD;
762
		    }
763

    
764
		    if(isset($config['snmpd']['modules']['hostres'])) {
765
			$snmpdconf .= <<<EOD
766
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
767

    
768
EOD;
769
		    }
770
		    if(isset($config['snmpd']['modules']['bridge'])) {
771
			$snmpdconf .= <<<EOD
772
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
773
# config must end with blank line
774

    
775

    
776
EOD;
777
		    }
778
		}
779

    
780
		fwrite($fd, $snmpdconf);
781
		fclose($fd);
782

    
783
		if (isset($config['snmpd']['bindlan'])) {
784
			$bindlan = "";
785
		}
786

    
787
		/* run bsnmpd */
788
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
789
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
790

    
791
		if ($g['booting'])
792
			echo "done.\n";
793
	}
794

    
795
	return 0;
796
}
797

    
798
function services_proxyarp_configure() {
799
	global $config, $g;
800
	if(isset($config['system']['developerspew'])) {
801
		$mt = microtime();
802
		echo "services_proxyarp_configure() being called $mt\n";
803
	}
804

    
805
	/* kill any running choparp */
806
	killbyname("choparp");
807

    
808
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
809
		$paa = array();
810

    
811
		/* group by interface */
812
		foreach ($config['virtualip']['vip'] as $vipent) {
813
			if ($vipent['mode'] === "proxyarp") {
814
				if ($vipent['interface'])
815
					$if = $vipent['interface'];
816
				else
817
					$if = "wan";
818

    
819
				if (!is_array($paa[$if]))
820
					$paa[$if] = array();
821

    
822
				$paa[$if][] = $vipent;
823
			}
824
		}
825

    
826
		if (count($paa))
827
		foreach ($paa as $paif => $paents) {
828
			$paaifip = get_interface_ip($paif);
829
			if (!(is_ipaddr($paaifip)))
830
                               continue;
831

    
832
			$args = get_real_interface($paif) . " auto";
833

    
834
			foreach ($paents as $paent) {
835

    
836
				if (isset($paent['subnet']))
837
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
838
				else if (isset($paent['range']))
839
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
840
						$paent['range']['to']);
841
			}
842

    
843
			mwexec_bg("/usr/local/sbin/choparp " . $args);
844
		}
845
	}
846
}
847

    
848
function services_dnsupdate_process() {
849
	global $config, $g;
850
	if(isset($config['system']['developerspew'])) {
851
		$mt = microtime();
852
		echo "services_dnsupdate_process() being called $mt\n";
853
	}
854

    
855
	/* Dynamic DNS updating active? */
856
	if (is_array($config['dnsupdates']['dnsupdate'])) {
857
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
858
		if (!isset($dyndns['enable']))
859
				continue;
860
			/* determine interface name */
861
			if ($dyndns['interface'] == "wan")
862
				$if = get_real_interface();
863
			else
864
				$if = convert_friendly_interface_to_real_interface_name($dyndns['interface']);
865

    
866
			$wanip = get_interface_ip($if);
867
			if ($wanip) {
868

    
869
				$keyname = $dnsupdate['keyname'];
870
				/* trailing dot */
871
				if (substr($keyname, -1) != ".")
872
					$keyname .= ".";
873

    
874
				$hostname = $dnsupdate['host'];
875
				/* trailing dot */
876
				if (substr($hostname, -1) != ".")
877
					$hostname .= ".";
878

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

    
888
EOD;
889
				fwrite($fd, $privkey);
890
				fclose($fd);
891

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

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

    
908
				/* generate update instructions */
909
				$upinst = "";
910
				if (!empty($dnsupdate['server']))
911
					$upinst .= "server {$dnsupdate['server']}\n";
912
				$upinst .= "update delete {$dnsupdate['host']} A\n";
913
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
914
				$upinst .= "\n";	/* mind that trailing newline! */
915

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

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

    
931
	return 0;
932
}
933

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

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

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

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

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

    
978
DebugLevel	2
979

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

    
982
IpVersion	4
983

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

    
986
ClearScreen     yes
987

    
988
{$enableannounce}
989

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

    
995
AllowNoInt	yes
996

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

    
1001
#TosValue	16
1002

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

    
1008
#Willingness    	4
1009

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

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

    
1019
     MaxConnections  0
1020

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

    
1025
     Host            127.0.0.1
1026
     #Host            10.0.0.5
1027

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

    
1032
     #Net             192.168.1.0 255.255.255.0
1033
}
1034

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

    
1040
UseHysteresis	no
1041

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

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

    
1055

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

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

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

    
1067
LinkQualityWinSize	10
1068

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

    
1072
Pollrate	0.05
1073

    
1074

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

    
1085
TcRedundancy	2
1086

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

    
1096
MprCoverage	3
1097

    
1098
# Example plugin entry with parameters:
1099

    
1100
EODA;
1101

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

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

    
1111
EODB;
1112

    
1113
}
1114

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

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

    
1123
EODC;
1124

    
1125
}
1126

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

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

    
1132
	$olsr .= <<<EODE
1133

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

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

    
1150
EODE;
1151

    
1152
}
1153

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

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

    
1165
    # HELLO validity time
1166
    HelloValidityTime	20.0
1167

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

    
1171
    # TC validity time
1172
    TcValidityTime	30.0
1173

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

    
1177
    # MID validity time
1178
    MidValidityTime	30.0
1179

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

    
1183
    # HNA validity time
1184
    HnaValidityTime 	30.0
1185

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

    
1194
    # Weight 0
1195

    
1196

    
1197
}
1198

    
1199
EODAD;
1200

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

    
1208
	if(is_process_running("olsrd"))
1209
		mwexec("/usr/bin/killall olsrd", true);
1210

    
1211
	sleep(2);
1212

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

    
1215
	conf_mount_ro();
1216
}
1217

    
1218
/* configure cron service */
1219
function configure_cron() {
1220
	global $g, $config;
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
function upnp_action ($action) {
1266
	switch($action) {
1267
		case "start":
1268
			if(file_exists('/var/etc/miniupnpd.conf'))
1269
				mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf');
1270
			break;
1271
		case "stop":
1272
			while((int)exec("pgrep miniupnpd | wc -l") > 0)
1273
				mwexec('killall miniupnpd 2>/dev/null', true);
1274
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1275
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1276
			break;
1277
		case "restart":
1278
			upnp_action('stop');
1279
			upnp_action('start');
1280
			break;
1281
	}
1282
}
1283

    
1284
function upnp_start() {
1285
	global $config, $g;
1286
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1287
		if($g['booting']) {
1288
			echo "Starting UPnP service... ";
1289
			include('/usr/local/pkg/miniupnpd.inc');
1290
			sync_package_miniupnpd();
1291
			echo "done.\n";
1292
		}
1293
		else {
1294
			upnp_action('start');
1295
		}
1296
	}
1297
}
1298

    
1299
?>
(29-29/40)