Browse Source

Finished WOL function (not tested)

Toby Chui 3 years ago
parent
commit
60f442f1d2

+ 1 - 0
cluster.go

@@ -56,6 +56,7 @@ func ClusterInit() {
 
 
 		router.HandleFunc("/system/cluster/scan", NeighbourDiscoverer.HandleScanningRequest)
 		router.HandleFunc("/system/cluster/scan", NeighbourDiscoverer.HandleScanningRequest)
 		router.HandleFunc("/system/cluster/record", NeighbourDiscoverer.HandleScanRecord)
 		router.HandleFunc("/system/cluster/record", NeighbourDiscoverer.HandleScanRecord)
+		router.HandleFunc("/system/cluster/wol", NeighbourDiscoverer.HandleWakeOnLan)
 
 
 		/*
 		/*
 			Start and Cluster Server and Client
 			Start and Cluster Server and Client

+ 63 - 0
mod/cluster/wakeonlan/wakeonlan.go

@@ -0,0 +1,63 @@
+package wakeonlan
+
+import (
+	"errors"
+	"net"
+	"time"
+)
+
+/*
+	Wake On Lan
+	Author: tobychui
+
+	This module send wake on LAN signal to a given MAC address
+	and do nothing else
+*/
+
+type magicPacket [102]byte
+
+func WakeTarget(macAddr string) error {
+	packet := magicPacket{}
+	mac, err := net.ParseMAC(macAddr)
+	if err != nil {
+		return err
+	}
+
+	if len(mac) != 6 {
+		return errors.New("Invalid MAC address")
+	}
+
+	//Initialize the packet with all F
+	copy(packet[0:], []byte{255, 255, 255, 255, 255, 255})
+	offset := 6
+
+	for i := 0; i < 16; i++ {
+		copy(packet[offset:], mac)
+		offset += 6
+	}
+
+	//Most devices listen to either port 7 or 9, send to both of them
+	err = sendPacket("255.255.255.255:7", packet)
+	if err != nil {
+		return err
+	}
+
+	time.Sleep(30 * time.Millisecond)
+
+	err = sendPacket("255.255.255.255:9", packet)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func sendPacket(addr string, packet magicPacket) error {
+	conn, err := net.Dial("udp", addr)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	_, err = conn.Write(packet[:])
+	return err
+}

+ 18 - 0
mod/network/neighbour/handler.go

@@ -40,6 +40,7 @@ func (d *Discoverer) HandleScanningRequest(w http.ResponseWriter, r *http.Reques
 	sendJSONResponse(w, string(js))
 	sendJSONResponse(w, string(js))
 }
 }
 
 
+//Get networkHosts that are offline
 func (d *Discoverer) HandleScanRecord(w http.ResponseWriter, r *http.Request) {
 func (d *Discoverer) HandleScanRecord(w http.ResponseWriter, r *http.Request) {
 	offlineNodes, err := d.GetOfflineHosts()
 	offlineNodes, err := d.GetOfflineHosts()
 	if err != nil {
 	if err != nil {
@@ -55,3 +56,20 @@ func (d *Discoverer) HandleScanRecord(w http.ResponseWriter, r *http.Request) {
 
 
 	sendJSONResponse(w, string(js))
 	sendJSONResponse(w, string(js))
 }
 }
+
+//Send wake on land to target
+func (d *Discoverer) HandleWakeOnLan(w http.ResponseWriter, r *http.Request) {
+	mac, err := mv(r, "mac", false)
+	if err != nil {
+		sendErrorResponse(w, "Invalid mac address")
+		return
+	}
+
+	err = d.SendWakeOnLan(mac)
+	if err != nil {
+		sendErrorResponse(w, err.Error())
+		return
+	}
+
+	sendOK(w)
+}

+ 6 - 0
mod/network/neighbour/neighbour.go

@@ -5,6 +5,7 @@ import (
 	"log"
 	"log"
 	"time"
 	"time"
 
 
+	"imuslab.com/arozos/mod/cluster/wakeonlan"
 	"imuslab.com/arozos/mod/database"
 	"imuslab.com/arozos/mod/database"
 	"imuslab.com/arozos/mod/network/mdns"
 	"imuslab.com/arozos/mod/network/mdns"
 )
 )
@@ -151,6 +152,11 @@ func (d *Discoverer) GetOfflineHosts() ([]*HostRecord, error) {
 	return results, nil
 	return results, nil
 }
 }
 
 
+//Try to wake on lan one of the network host
+func (d *Discoverer) SendWakeOnLan(macAddr string) error {
+	return wakeonlan.WakeTarget(macAddr)
+}
+
 func (d *Discoverer) ScannerRunning() bool {
 func (d *Discoverer) ScannerRunning() bool {
 	if d.d != nil {
 	if d.d != nil {
 		return true
 		return true

+ 30 - 3
web/SystemAO/cluster/neighbour.html

@@ -132,7 +132,6 @@
                             }) 
                             }) 
                             var ipDOM = iplinks.join(" / ");
                             var ipDOM = iplinks.join(" / ");
                             var macDOM = host.MacAddr.join(" / ");
                             var macDOM = host.MacAddr.join(" / ");
-                            console.log(host.MacAddr);
                             if (host.MacAddr.length == 0){
                             if (host.MacAddr.length == 0){
                                 //Old version of ArozOS, do not support MAC addr broadcast
                                 //Old version of ArozOS, do not support MAC addr broadcast
                                 macDOM = "Version Not Supported";
                                 macDOM = "Version Not Supported";
@@ -196,13 +195,17 @@
                             ipDOM = host.LastSeenIP.join(" / ");
                             ipDOM = host.LastSeenIP.join(" / ");
                         }
                         }
                         let macDOM = "No Record";
                         let macDOM = "No Record";
+                        let wakeOnLanButton = "";
                         if (host.MacAddr != null && host.MacAddr.length > 0){
                         if (host.MacAddr != null && host.MacAddr.length > 0){
                             macDOM = host.MacAddr.join(" / ");
                             macDOM = host.MacAddr.join(" / ");
+                            wakeOnLanButton = `<button class="ui right floated basic button" mac="${encodeURIComponent(JSON.stringify(host.MacAddr))}" onclick="wakeonlan(this);"><i class="power icon"></i> Wake On LAN</button>`;
                         }
                         }
+                        
+                       
                         $("#offlineList").append(`<div class="ui icon message">
                         $("#offlineList").append(`<div class="ui icon message">
-                            <i class="server icon"></i>
+                         <i class="server icon"></i>
                             <div class="content">
                             <div class="content">
-                                <button class="ui right floated basic button"><i class="power icon"></i> Wake On LAN</button>
+                                ${wakeOnLanButton}
                                 <div class="header">
                                 <div class="header">
                                     <span>${host.Name}</a>
                                     <span>${host.Name}</a>
                                 </div>
                                 </div>
@@ -252,6 +255,30 @@
             });
             });
         }
         }
 
 
+        function wakeonlan(object){
+            $(object).addClass("disabled");
+            let macAddr = $(object).attr("mac");
+            macAddr = JSON.parse(decodeURIComponent(macAddr));
+            let counter = macAddr.length;
+            macAddr.forEach(function(thisMac){
+                $.get("../../system/cluster/wol?mac=" + thisMac, function(data){
+                    console.log("Wake On Lan packet sent to "  + thisMac + " with results: "+ data);
+                    counter--;
+                    if (counter == 0){
+                        //All WOL packet has been sent
+                        let currentButtonText = $(object).html();
+                        $(object).addClass("green").addClass("icon");;
+                        $(object).html(`<i class="green checkmark icon"></i>`);
+                        setTimeout(function(){
+                            $(object).removeClass("green").removeClass("remove");
+                            $(object).html(currentButtonText);
+                            $(object).removeClass("disabled");
+                        }, 5000)
+                    }
+                });
+            });
+            
+        }
        
        
     </script>
     </script>
 </body>
 </body>