PHP & Wake on Lan: Problem mit Broadcast im Heimnetz

Darklord543

Lieutenant
Registriert
März 2010
Beiträge
565
Heyo,

ich versuche gerade von einer kleinen Webseite die bei mir daheim auf dem NAS liegt, meine Heimrechner zu starten.
Das Problem das ich mit Wake on Lan habe: Es funktioniert nur solange ich die Ziel-IP eingebe, ein Broadcast im 192.168.1.255 Netz folgt in dem Fehler:

Warning: fsockopen(): unable to connect to udp://192.168.1.255:9 (Permission denied) in /volume1/web/StefanNB-PC.php on line 7 Warnung: 13 Permission denied

Da ich wenig Erfahrung mit PHP habe weis ich nicht genau wo ich den Fehler suchen muss.
Liegt das vielleicht an der PHP-Integration des Synology NAS welches die Seite hostet?
Macht dann das NAS oder der Router im Netz den Broadcast auf 192.168.1.255?

Der Code:

PHP:
<?php

$mac = 'B0DDF139C268'; 											//MAC Adresse
$ip = 'udp://192.168.1.255'; 									//oder mit IP z.B.: udp://192.168.0.1

function wakeup($mac_addr,$router_addr) {
	if ($fp = fsockopen($router_addr, 9, $errno, $errstr, 4)) {		
		$hexchars = array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","a","b","c","d","e","f");//erlaubte Zeichen:	
		$data = "\xFF\xFF\xFF\xFF\xFF\xFF";						// 6 "volle" bytes (Also mit Wert 255 bzw. FF in hexadezimal)
		$hexmac = "";
		for ($i = 0; $i < strlen($mac_addr); $i++) {			// Unntige Zeichen in der mac-adresse entfernen (also z.B. die bindestriche usw.)
			if (!in_array(substr($mac_addr, $i, 1), $hexchars)) {
				$mac_addr = str_replace(substr($mac_addr, $i, 1), "",
				$mac_addr);
			}
		}
		for ($i = 0; $i < 12; $i += 2) {
			$hexmac .= chr(hexdec(substr($mac_addr, $i, 2)));
		}
			
		for ($i = 0; $i < 16; $i++) {							// Hexadresse wird 16mal hintereinandergeschrieben
			$data .= $hexmac;
		}
		fputs($fp, $data);
		fclose($fp);
		echo 'MagicPaket wurde verschickt';
		return true;
	}
	Else {
		echo "<b>Warnung: $errno</b> $errstr<br>";
		return false;
	}
}

wakeup($mac, $ip);

?>
 
Zuletzt bearbeitet:
Ich hab keine Ahnung von PHP, hab aber eben auf die schnelle folgenden Code gefunden mit dem Kommentar: "Here's how you can make an udp broadcast, useful sometimes, and does seem hard to figure out hwo to do.. "

PHP:
<?php 
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1); 
socket_sendto($sock, $broadcast_string, strlen($broadcast_string), 0, '255.255.255.255', $port); 
?>

Quelle: http://php.net/manual/en/function.socket-sendto.php
 
Kann das mit socket_create überhaupt funktionieren? Ich hab ja keinen Socket der "zuhört", die Netzwerkkarten von den ausgeschalteten PCs lesen ja nur mit und warten auf ein Magic Packet?
 
Wenn ich mich recht entsinne, wird das WoL Packet auf einer OSI Schicht versendet, auf der du in PHP gar nicht arbeiten kannst. Das Packet war zwar wie ein UDP-Packet aufgebaut, aber wurde nicht über UDP sondern direkt Ethernet gesendet, also weit unterhalb im Schichtenmodell auf dem du sonst arbeiten würdest oder arbeiten kannst.

Ich würde mal lieber nach einer Möglichkeit suchen direkt durch das Betriebssystem den WoL auslösen zu lassen und dies dann durch PHP ansprechen, ggf. eben indem du über PHP per exec() ein kleines C-Programm aufrufst.
 
Es funktioniert nur solange ich die Ziel-IP eingebe, ein Broadcast im 192.168.1.255 Netz folgt in dem Fehler:

Warning: fsockopen(): unable to connect to udp://192.168.1.255:9 (Permission denied) in /volume1/web/StefanNB-PC.php on line 7 Warnung: 13 Permission denied

@ice-breaker: Es funktioniert ja, der Fehler taucht beim Broadcast auf, weil du einen Port mit angibst (den braucht man um von außerhalb einen Broadcast über den Router ins Netz zu schicken)... wie du das innerhalb deines Netzwerks richten musst, kann ich dir aber auch nicht sagen...
 
Hier ist ein anscheinend funktionsfähiges PHP-Script das WOL implementiert. Die Quelle soll die offizielle PHP Seite sein:

http://forum.qnap.com/viewtopic.php?p=202661#p202661

PHP:
<?php 
# Wake on LAN - (c) HotKey (at SPR dot AT), upgraded by Murzik <tomurzik@inbox.ru> 

flush(); 

function WakeOnLan($addr, $mac) 
{ 
$addr_byte = explode(':', $mac); 
$hw_addr = ''; 

for ($a=0; $a < 6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a])); 

$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255); 

for ($a = 1; $a <= 16; $a++) $msg .= $hw_addr; 

// send it to the broadcast address using UDP 
// SQL_BROADCAST option isn't help!! 
$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
if ($s == false) 
{ 
echo "Error creating socket!\n"; 
echo "Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)); 
} 
else 
{ 
// setting a broadcast option to socket: 
$opt_ret = socket_set_option($s, 1, 6, TRUE); 
if($opt_ret < 0) 
{ 
echo "setsockopt() failed, error: " . strerror($opt_ret) . "\n"; 
} 
$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050); 
echo $e;
socket_close($s); 
echo "Magic Packet sent (".$e.") to ".$addr.", MAC=".$mac; 
} 
} 

#WakeOnLan('yourIPorDomain.dyndns.org', 'your:MAC:address'); 
#WakeOnLan('192.168.0.2', '00:30:84:2A:90:42'); 
#WakeOnLan('192.168.1.2', '00:05:1C:10:04:05'); 

//if you have switch or other routing devices in LAN, sendign to 
// the local IP isn't helps! you need send to the broadcast address like this: 
WakeOnLan('192.168.0.255', 'xx:xx:xx:xx:xx:xx'); 

?>
 
Das gleiche habe ich eben auch gefunden, und ich muss sagen: Es funktioniert! :)

Vielen Dank für die Hilfe
 
Das Script geht? Bei mir nicht :(

Ich habe genau das selbe Problem mit den NSA320 von Zyxel :(
Zuvor hatte ich genau das selbe Script wie der Ersteller des Themas mit genau den selben Problem. Muss nur noch sagen, dass mit der 255 aber auf mein xampp- Server noch ging, erst auf den NSA nicht :(

Deshalb habe ich voller Hoffnung das letzte Script genommen welches funktionieren soll, tut es aber nicht :(

PHP:
<?php
$router = "192.168.1.255";                      // ip des Routers

$mac = $_GET["mac"];

if (isset($_POST["up"])) {
  $mac = $_POST["mac"];
}

wakeup($router, $mac);

 flush();

 function wakeup($addr, $mac)
 {
 $addr_byte = explode('-', $mac);
 $hw_addr = '';

 for ($a=0; $a < 6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a]));

 $msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);

 for ($a = 1; $a <= 16; $a++) $msg .= $hw_addr;

 // send it to the broadcast address using UDP
 // SQL_BROADCAST option isn't help!!
 $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
 if ($s == false)
 {
 echo "Error creating socket!\n";
 echo "Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s));
 }
 else
 {
 // setting a broadcast option to socket:
 $opt_ret = socket_set_option($s, 1, 6, TRUE);
 if($opt_ret < 0)
 {
 echo "setsockopt() failed, error: " . strerror($opt_ret) . "\n";
 }
 $e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
 echo $e;
 socket_close($s);
 echo "Magic Packet sent (".$e.") to ".$addr.", MAC=".$mac;
 }
 }

?>

Folgende Fehlermeldungen kommen:
HTML:
Warning: socket_create() expects parameter 3 to be long, string given in /i-data/e7e241ba/server/pages/wakeup.php on line 35
 Error creating socket! 
Warning: socket_last_error() expects parameter 1 to be resource, null given in /i-data/e7e241ba/server/pages/wakeup.php on line 39

Warning: socket_last_error() expects parameter 1 to be resource, null given in /i-data/e7e241ba/server/pages/wakeup.php on line 39
 Error code is '' - Success

Kann mir einer einen Tipp geben und mir sagen warum es nicht bei mir funzt?

Grüße und danke im Vorraus
Coddi
 
Deine Fehlerauswertung bekommt als Parameter NULL statt dem Rückgabewert $s der Funktion socket_create! Da liegt wohl der Fehler!

Bist du sicher, dass deine Adresse 192.168.1.255 die deines Routers ist? Meines Wissens sind 0 und 255 für Broadcast reserviert... Hast du mal eine andere probiert, zum Beispiel die des PCs den du wecken willst??
 
Hi,

es lag daran, dass das Linux meines NSA320 keine etc/protocol hatte, welches diese socket- Funktion braucht.
Abhilfe schaffte einfach den letzten Parameter eine 17 zu übergeben statt SQL_UDP.
Die 17 steht in der besagten Datei
 
ice-breaker schrieb:
Das Packet war zwar wie ein UDP-Packet aufgebaut, aber wurde nicht über UDP sondern direkt Ethernet gesendet, also weit unterhalb im Schichtenmodell auf dem du sonst arbeiten würdest oder arbeiten kannst.

Ganz grob: WOL findet prinzipiell auf der Ethernet-Ebene statt, stimmt. Dabei durchforstet die Netzwerkkarte aber eigentlich nur die eingehenden Frames auf ein spezielles Pattern und ignoriert alles andere, was bedeutet, dass man das Pattern in verschiedene Protokolle einbetten kann, zum Beispiel eben UDP. Das macht die Anwendung dann einfacher.
 
Zurück
Oben