# Wake On LAN



## Kai-DD (16. Aug 2004)

Hallo!

Ich suche schon länger vergebens nach einem kurzen Beispiel, um WOL über Java zu realisieren.
Ich weiß, dass dabei ein Magic-Packet über UDP (Datagram-Socket) gesendet wird, aber bekomme das bei mir nicht hin. Das Magic-Packet soll auch in andere Netze verschickt werden (Broadcast).
Ein paar Zeilen Quell-Code mit der Lösung des Problems, also dem Erzegen des Magic-Packet aus der MAC und dem Öffenen des Sockets und Absenden des entsprechenden Pakets wäre ich dankbar.

Grüße, Kai


----------



## thE_29 (16. Aug 2004)

naja, wenn du weißt das ein MagicPacket drübergeschickt wird, weißt du mehr als ich 

wie muss dieses Paket aussehen? UDP Paket schicken ist danach net wirklich schwer!


----------



## Kai-DD (16. Aug 2004)

Das MagicPacket ist von AMD "erfunden" und besteht aus 6 x FF und 16 x MAC:
DESTINATION SOURCE MISC. FF FF FF FF FF FF 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 MISC. CRC
So stehts bei AMD, aber ich weiß nicht wo die Broadcast-Adresse hin soll und was MISC und CRC sind. Damit komm ich eben nicht weiter. GHab gelesen, das bei UDP auch noch das Format, was ja nun Hexadezimal ist, geändert werden soll. viel mehr weiß ich aber dazu nicht. Ich hab sowas für Perl am laufen und es gibt Beispiele für andere Sprachen, aber anscheindend nicht für JAVA...


----------



## Grizzly (16. Aug 2004)

Ich dachte immer, das Wake On Lan vom Mainboard und der Netzwerkkarte realisiert werden würde - ohne irgendwelche Software. ???:L


----------



## Grizzly (16. Aug 2004)

Kai-DD hat gesagt.:
			
		

> Das MagicPacket ist von AMD "erfunden" und besteht aus 6 x FF und 16 x MAC:
> DESTINATION SOURCE MISC. FF FF FF FF FF FF 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 11 22 33 44 55 66 MISC. CRC
> So stehts bei AMD, aber ich weiß nicht wo die Broadcast-Adresse hin soll und was MISC und CRC sind. Damit komm ich eben nicht weiter. GHab gelesen, das bei UDP auch noch das Format, was ja nun Hexadezimal ist, geändert werden soll. viel mehr weiß ich aber dazu nicht. Ich hab sowas für Perl am laufen und es gibt Beispiele für andere Sprachen, aber anscheindend nicht für JAVA...


Bist Du sicher, dass man in Java IP Packete überhaupt soweit modifizieren kann? ???:L


----------



## Kai-DD (16. Aug 2004)

Na klar, aber die Netzwerkkarte muss eben das Signal empfangen, erkennt an der MAC "Ich soll einschalten" und senden übers BIOS an das Board "Einschalten".
Es geht hier aber um das Senden dieses Signals mit JAVA.


----------



## Kai-DD (16. Aug 2004)

Ja, bin mir sicher.
Das gibts auch schon, aber die Lösung ist für mich unbrauchbar und ich kann mir den nötigen Teil aus dem Source nicht extrahieren:
http://www.i-konzept.de/moldaner/wakeonlan/wakeonlan.html
Bei AMD gibts Infos hier:
http://www.amd.com/de-de/ConnectivitySolutions/TechnicalResources/0,,50_2334_2481,00.html


----------



## thE_29 (16. Aug 2004)

der baut dir doch den Frame zusammen


```
//Schickt die Befehl und baut sie zusammen
	public static void wakeup(EthernetAddress[] ethernetAddresses, InetAddress host, int port) throws IOException {
		DatagramSocket socket = new DatagramSocket();
		
		for (int i = 0; i < ethernetAddresses.length; i++) {
			byte[] wakeupFrame = createWakeupFrame(ethernetAddresses[i]);
			
			DatagramPacket packet = new DatagramPacket(wakeupFrame, wakeupFrame.length, host, port);
			
			socket.send(packet);
		}
	}



	protected static byte[] createWakeupFrame(EthernetAddress ethernetAddress) {
		byte[] ethernetAddressBytes = ethernetAddress.toBytes();
		byte[] wakeupFrame = new byte[6 + 16 * ethernetAddressBytes.length];
		
		Arrays.fill(wakeupFrame, 0, 6, (byte)0xFF);
        
		for (int j = 6; j < wakeupFrame.length; j += ethernetAddressBytes.length) {
			System.arraycopy(ethernetAddressBytes, 0, wakeupFrame, j, ethernetAddressBytes.length);
		}
		
		return wakeupFrame;
	}
```

dann musst du noch die Klasse ethernetAddress einbinden, nachsehen was der verlangt

ich schätz mal das ethernetAddress die MAC Addresse sein soll! Würd die von innen genommen Klasse verwenden!


----------



## Kai-DD (16. Aug 2004)

Ja, und genau da komm ich mit meinen Anfängerkenntnissen nicht weiter.
Wenn ich die 2 Teile in eine neue Datei in ein neues Projekt in Eclipse einfüge,  kommen jede Menge Fehler. Wenn ich ann die ganze Datei EthernetAddress noch hinzufüge und versuche alles anzupassen , kommen noch mehr Fehler. Es scheint, als müsste ich dann alles aus dem ursprünglichen Projekt einbinden.
Dabei brauch ich ja eigentlich nur die Zeilen:

```
DatagramPacket packet = new DatagramPacket(wakeupFrame, wakeupFrame.length, host, port);
socket.send(packet);
```
und muss wissen wie ich einfach wakeupFrame bekomme. Außerdem bin ich mir noch nicht so sicher, ob host vielleicht die broadcastadresse sein soll und welche Formate (also String, int, usw.) wakeupFrame, host, port haben müssen.


----------



## thE_29 (17. Aug 2004)

also ich kanns einfügen und es geht 

Ethernetaddress machst mit new EthernetAddress("AA:BB:XX:CC:FF:SS");


```
public static void wakeup(EthernetAddress[] ethernetAddresses, InetAddress host, int port) throws IOException {
		DatagramSocket socket = new DatagramSocket();
		
		for (int i = 0; i < ethernetAddresses.length; i++) {
			byte[] wakeupFrame = createWakeupFrame(ethernetAddresses[i]);
			
			DatagramPacket packet = new DatagramPacket(wakeupFrame, wakeupFrame.length, host, port);
			
			socket.send(packet);
		}
	}
```

und host ist der host was du senden willst (255.255.255.255 ist broadcast) und port solltest bei 9 lassen!


----------



## Kai-DD (17. Aug 2004)

Ich glaub jetzt hab ich was zusammengebaut, was zumindest mal keine Fehler bringt. Schön. Dazu hab ich 3 Dateien in ein Eclipse-Projekt erstellt.

wol.java:

```
import java.io.*;
import java.net.*;
import java.util.*;

public class wol {
	
	public static void main(String[] Args) throws IllegalEthernetAddressException, IOException {
		String MAC = "AA:BB:CC:DD:EE:FF";
		InetAddress host = InetAddress.getByName("MeinPCName"); //liefert lok. Namen und IP
		int port = 9;
		EthernetAddress[] NIC = {new EthernetAddress(MAC)};
		wakeup(NIC, host, port);

	}
	
	public static void wakeup(EthernetAddress[] ethernetAddresses, InetAddress host, int port) throws IOException {
		DatagramSocket socket = new DatagramSocket();
		
		for (int i = 0; i < ethernetAddresses.length; i++) {
			byte[] wakeupFrame = createWakeupFrame(ethernetAddresses[i]);
			
			DatagramPacket packet = new DatagramPacket(wakeupFrame, wakeupFrame.length, host, port);
			
			socket.send(packet);
		}
	}
	
	protected static byte[] createWakeupFrame(EthernetAddress ethernetAddress) {
		byte[] ethernetAddressBytes = ethernetAddress.toBytes();
		byte[] wakeupFrame = new byte[6 + 16 * ethernetAddressBytes.length];
		
		Arrays.fill(wakeupFrame, 0, 6, (byte)0xFF);
        
		for (int j = 6; j < wakeupFrame.length; j += ethernetAddressBytes.length) {
			System.arraycopy(ethernetAddressBytes, 0, wakeupFrame, j, ethernetAddressBytes.length);
		}
		
		return wakeupFrame;
	}
}
```

und die kompletten, unveränderten Dateien IllegalEthernetAddressException.java und EthernetAddress.java.

Dabei Frage ich mich aber wozu ich den Host brauche, da das doch mein eigener Rechner ist. Wenn das doch nicht mei eigener Rechner ist, die IP und der Name des einzuschaltenden Zielsystems ist doch aber auch irrelevant, da nur die MAC benötigt wird??
Wie und an welcher Stelle muss ich nun noch die Broadcast-IP angeben, denn die benötige ich unbedingt, da die meißten Clients in anderen Netzen sind?

_edited by thE_29: code tags entfernt_


----------



## thE_29 (17. Aug 2004)

also, host ist die Address an der dein PC ist!

Du kannst nur mit der MAC Address keinen Befehl hinschicken (wie den auch??!?!) die MAC Addresse braucht erzusätzlich halt noch, weil er damit das MagicPaket zusammenbaut!

Host musst du den PC angeben oder 255.255.255.255 (laut Hilfe im source) ist das die broadcast address!

also, wenn du host sagst deine addresse, schickst du ein paket an deine address, sehr sinnvoll, wenn du einen anderen PC aufwecken willst 


Aber du musst ja eigentlich sowieso die Broadcast nehmen, da dein PC wenn er ausgeschaltet ist, ja eigentlich keine IP address hat! Schätz ich halt, hab zwar einen PC mit WOL aber das kabel is net angesteckt!


----------



## Kai-DD (17. Aug 2004)

Aha, nein ich möchte natürlich nicht meinen PC, sondern einen PC in einem ANDEREN Teilnetz aufwecken und dazu brauch ich die Broadcast, da sonst das Packet gar nicht erst in dem entsprechenden Teilnetz ankommt.

In jedem Teilnetz hängen ca. 300 PC. Konkret hat z.B.: ein PC den Namen PC1 mit der IP 179.50.4.1 und der Broadcast-Adresse 179.50.7.255 (nicht zu verwechseln mit der Netz-Maske 255.255.252.0).

Diese Broadcast-Adresse muss nun irgendwie dem Paket ubergeben werden. Ich weiß aber nicht wie, ob im Magic-Paket oder irgendwie bei UPP absenden.

Wenn ich das nun richtig verstanden hab, ist die 255.255.255.255 default. Ich versuch einfach mal anstelle derer die richtige Broadcast zu verwenden.


----------



## Kai-DD (17. Aug 2004)

Es funktioniert so!!
Nun muss ich dass nun noch in meine Umgebung reinbasteln.

Danke für die Unterstützung!
Kai


----------



## thE_29 (17. Aug 2004)

also was hast du jetzt für host eingetragen?

die broadcast address vom PC oder die SubnetMaske?

Selber gerne wissen will


----------



## Kai-DD (17. Aug 2004)

Für host hab ich nun die Broadcast-Adresse des Teilnetzes in dem sich der aufzuweckende PC befindet eingesetzt. Diese Adresse wird jedoch nicht Teil des Magic Packet sondern sorgt wohl beim Aufruf von:

```
DatagramPacket packet = new DatagramPacket(wakeupFrame, wakeupFrame.length, host, port);
```
dafür, dass das Paket überhaupt erst mal ins richtige Teilnetz sendet. Hätte mich ja uch gewundert, da IP des eigenen und Fremdrechners ja völlig egal sein müssten....


----------



## thE_29 (17. Aug 2004)

das war ja klar, da dein paket nichts von deiner IP addresse beinhaltet 

Habe schon UDP Server gemacht und die die IP addresse (host) sagt nur wohin, nicht was drinnen steht!


----------



## thE_29 (17. Aug 2004)

nachwas!

bei einer so WOL NIC muss man das Kabel am MB auch wo reinstecken oder?




EDIT

Also, Kabel hab ich angesteckt (hoffe dass das richtig war) und im BIOS auch auf AN nur der fährt net hoch!

Bin aber über Router, bist du direkt verbunden?

und du hast gepostet das deine Broadcast addr eine 7 hat und die normale eine 4, ist das ein Fehler?


----------



## Kai-DD (18. Aug 2004)

Die Fehlersuche gestaltet sich bei sowas immer recht kompliziert.

Wir nehmen mal an, dass es also nicht an unserem JAVA-WOL-Tool liegt, da es ja bei mir wunderbar funktioniert, außer du hast bei dem sendenden PC eine Firewall, so dass das Signal nicht raus kommt??
Bei Routern muss es aber auch noch Optionen geben, sonst kommt vieleicht auch da das Magic-Packet nicht durch.

Dann wäre noch der Zielrechner. Bei dem muss im BIOS alles ok aktiv sein. Das Kabel von der NIC zum MB muss angesteckt sein. Mehr eigentlich nicht. Manchmal müssen die Rechner aber schon unter Strom gestanden haben, also nicht gerade frisch ans Stromnetz gesteckt, oder auch nicht von Hand im Booten ausgeschalten. Ich habe aber auch schon Boards erlebt, bei denen im Bios nicht nur das WOL enabled sein musste, sondern auch zusätzlich Wake up by PCI-Card (oder so ähnlich) enabled.

Im selben Netz ist kein Broadcast erforderlich. Am besten du versuchst es erstmal mit einen Win-Tool wie winwake.exe, was als einzigen Parameter die MAC benötigt. Im selben Netz ist die Broadcast die IP des Zielsystems mit 255 im 4. Byte z.B.: IP-Ziel 192.168.1.10 --> Broadcast 192.168.1.255 (beide im 1er Teilnetz).

Eine Abweichung des BC tritt nur auf, wenn man z.B. 3 Nummern des 3. Bytes für 1 Teilnetz reservieren will, da die 255 möglichen Geräte eines "normalen" Teilnetzes nie ausreichen würden (Netzdrucker, PCs, Notebooks, aber auch Server und Netzkomponenten haben IPs). Z.B.: IP-Range für 1. Teilnetz 192.168.1.0-192.168.3.255, für 2. Teilnetz 192.168.4.0-192.168.6.255 usw. Dabei wäre Broadcast für 1. Netz 192.168.3.255 woraus sich dann auch für die Netmask statt 255.255.255.0 die 255.255.253.0 ergibt. Genauer kann ich das aber nicht erklären, da ich mit Netzwerken nicht so firm bin.


----------



## Grizzly (18. Aug 2004)

Kai-DD hat gesagt.:
			
		

> [...]Z.B.: IP-Range für 1. Teilnetz 192.168.1.0-192.168.3.255, für 2. Teilnetz 192.168.4.0-192.168.6.255 usw. Dabei wäre Broadcast für 1. Netz 192.168.3.255 woraus sich dann auch für die Netmask statt 255.255.255.0 die 255.255.253.0 ergibt. Genauer kann ich das aber nicht erklären, da ich mit Netzwerken nicht so firm bin.



Das stimmt so nicht :noe: . Deine Netze 192.168.1.x bis 192.168.6.x sind Klasse C Netze und können nur 254 "echte" IP-Adressen aufnehmen. Da hilft auch die Netmask nix. Mit der kannst Du die Netze nur noch weiter untergliedern, falls dies notwendig ist. In dem Fall hätte jeder der 6 Netze seine eigene Broadcast-Adresse: Jeweils a.b.c.255.

Bspw. im SuSE Linux Handbuch findest Du eine rudimentäre Erklärung zu IP-Adresse und IP-Netzwerken.


----------



## Kai-DD (18. Aug 2004)

Ja, wie gesagt, hab in der Netztechnik nicht so große Ahnung, lasse nich aber gern belehren. Darum kümmert sich hier das Netzmanagement und die Leute müssen das ja eigenlich nur wissen.
Auf jeden fall ist es so, dass ich bei WOL eines PC z.B. mit der IP 192.168.4.121 den Broadcast 172.29.7.255 angeben muss, damit es funktioniert. Mein PC selbst hängt z.B. in einem 192.x - Netz.


----------



## thE_29 (18. Aug 2004)

also ich habe ein 192.168.0.X netz, was muss ich da jetzt als broadcast angeben?

subnet ist 255.255.255.0


----------



## Kai-DD (18. Aug 2004)

Bei ein Netz 192.168.0.X kannst du theoretisch 256 Geräte einbinden (Daher auch 255.255.255.0 als Netmask).  Die höchste IP ist 192.168.0.255 - das ist auch die Broadcast-Adresse.

(255.255.255.255 als Broadcast sollte aber auch gehen, das heißt dann aber "flute alles" und sollte auf gar keinen Fall verwendet werden. Das is nix Gescheites.)


----------

