[WIN] Wake on LAN, WOL, Magic Packet

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

 

naibaf7

Betreff: [WIN] Wake on LAN, WOL, Magic Packet

BeitragDi, Okt 25, 2011 12:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Nach längerer Abwesenheit wieder mal etwas von mir. Der Code sollte Selbsterklärend sein.

Ob die Pakete auch wirklich abgeschickt werden, bzw. ankommen, lässt sich bestens mit Wireshark überprüfen, wenn man dort als Filter "wol" eingibt.
Dort sollten dann die Pakete angezeigt werden, mit 144 Bytes grösse:
102 Bytes davon sind unser Magic Packet, die restlichen 42 Bytes sind der UDP-Header. Die MAC-Adresse lässt sich dort direkt rauslesen.

Wenn man den PC von ausserhalb starten will, ist es wichtig, im Router DynDNS einzurichten oder eine statische IP zu besitzen. Zudem muss man IP-Forwarding/VirtualServer und Traffic-Inbound-Filter einrichten, damit die Pakete von aussen her (Port 9) nach innen umgelenkt werden können.
Da Router nicht Broadcasten muss zudem eine statische ARP und statische IP für den zu startenden PC eingerichtet werden.

Ansonsten muss man im BIOS wie auch im Betriebssystem-LAN-Treiber die WOL/Magic-Packet (nicht Pattern-Match) einschalten! Nicht alle BIOS/Treiber implementieren dies korrekt.


Code: [AUSKLAPPEN]


'Wake on LAN


SIP_int$ = "192.168.1.255"      'Broadcast interne IP
SURL_ext$ = "test.blabla.de"      'z.B. DYNDNS-Adresse
SMAC$ = "AA:BB:CC:DD:EE:FF"      'MAC-Adresse der Netzwerkkarte des zu startenden PCs




SIP_ext$ = URLtoIP(SURL_ext$)   'über Ping mit Process Pipe die IP der DynDNS URL bestimmen


SendWOL(SIP_int$,SMAC$)      'Interne IP muss Broadcast sein.
SendWOL(SIP_ext$,SMAC$)      'Externe IP. Achtung: Router und ARP-Route muss dafür richtig eingestellt sein.
                  'Funktioniert nur von anderen Netzwerken aus!


Function SendWOL(IP$,MAC$)               'Magic-Packet Sendefunktion
   socket:TSocket = CreateUDPSocket()
   Print ConnectSocket(socket,IPtoInt(IP$),9)

   bank:TBank = CreateBank(102)            '102 Bytes grosses Paket
   'Es ist hier anzumerken, dass es wichtig ist, erst das Paket zu erstellen, dann zu Senden.
   'Es funktioniert NICHT, die Bytes nacheinander mit WriteByte zu senden, da dadurch mehrere Pakete
   'gesendet werden!

   c=0

   For i = 0 To 5
      PokeByte(bank,c,$FF)            '6x FF
      c=c+1
   Next
   For i = 0 To 15                  '16x MAC
      PokeByte(bank,c,MactoHex(MAC$,0))
      c=c+1
      PokeByte(bank,c,MactoHex(MAC$,1))
      c=c+1
      PokeByte(bank,c,MactoHex(MAC$,2))
      c=c+1
      PokeByte(bank,c,MactoHex(MAC$,3))
      c=c+1
      PokeByte(bank,c,MactoHex(MAC$,4))
      c=c+1
      PokeByte(bank,c,MactoHex(MAC$,5))
      c=c+1
   Next
   Local pointer:Byte Ptr = LockBank(bank)
   socket.send(pointer,102)            'Paket abschicken
   UnlockBank(bank)
   CloseSocket(socket)
EndFunction

Function IPtoInt(serverIP$)               'Dotted-IP zu Int-IP
   serverIP$:+"."
   Local sect:String[4]
   For i = 0 To 3
      part =  serverIP$.find(".")
      sect[i] =  serverIP$[0..part]
      serverIP$ = serverIP$[part+1..]
   Next
   Return (sect[0].toint() Shl 24) + (sect[1].toint() Shl 16) + (sect[2].toint() Shl 8) + sect[3].toint()
EndFunction


Function MactoHex(mac$,off)               'Mac-String zu Hex-Int-Array
   'offset blocks: 0 to 5
   'mac: 6 blocks of 6 characters
   Local x[6]
   mac$ = Upper(mac$)
   For i = 1 To Len(mac$)
      t$ = Mid(mac$,i,1)
      If (Asc(t$) > 47 And Asc(t$) < 58) Or (Asc(t$) > 64 And Asc(t$) < 71) Then
         a$ = a$ + t$
      EndIf
   Next
   For i = 0 To 5
      v0 = Asc(Mid(a$,1+i*2))
      v1 = Asc(Mid(a$,2+i*2))
      If (v0 > 47 And v0 < 58) Then v0 = v0 - 48
      If (v1 > 47 And v1 < 58) Then v1 = v1 - 48
      If (v0 > 64 And v0 < 71) Then v0 = v0 - 55
      If (v1 > 64 And v1 < 71) Then v1 = v1 - 55
      x(i) = v0*16+v1
   Next
   Return x(off)
EndFunction


Function URLtoIP$(URL$)               'Web-URL zu Dotted-IP
   Local a$   
   proc:TProcess = TProcess.Create("ping "+URL$,0)
   time = MilliSecs()
   While proc
      If proc.pipe.ReadAvail()
         a$ = proc.pipe.ReadLine()
         If Instr(a$,"[") > 0
            IP$ = Mid(a$,Instr(a$,"[")+1,Instr(a$,"]")-Instr(a$,"[")-1)
            Return IP$
         EndIf
      EndIf
      If (MilliSecs() - time > 5000) Then
         Exit
      EndIf
   Wend
   IP$ = ""
   Return IP$
EndFunction


My Pc:
MSI 790FX-GD70, Phenom X4 955BE, 2x2GB DDR3-1600, 8800GTS-512, WD 640GB + Samsung 160GB, Scythe Kaze Master

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group