-
Notifications
You must be signed in to change notification settings - Fork 314
Expand file tree
/
Copy pathwol.go
More file actions
85 lines (71 loc) · 2.04 KB
/
wol.go
File metadata and controls
85 lines (71 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package kvm
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
wolPackets = promauto.NewCounter(
prometheus.CounterOpts{
Name: "jetkvm_wol_sent_packets_total",
Help: "Total number of Wake-on-LAN magic packets sent.",
},
)
wolErrors = promauto.NewCounter(
prometheus.CounterOpts{
Name: "jetkvm_wol_sent_packet_errors_total",
Help: "Total number of Wake-on-LAN magic packets errors.",
},
)
)
// SendWOLMagicPacket sends a Wake-on-LAN magic packet to the specified MAC address.
// broadcastIP optionally overrides the default 255.255.255.255 broadcast address.
func rpcSendWOLMagicPacket(macAddress string, broadcastIP string) error {
// Parse the MAC address
mac, err := net.ParseMAC(macAddress)
if err != nil {
wolErrors.Inc()
return ErrorfL(wolLogger, "invalid MAC address", err)
}
// Determine broadcast address
target := "255.255.255.255"
if broadcastIP != "" {
if ip := net.ParseIP(broadcastIP); ip == nil || ip.To4() == nil {
wolErrors.Inc()
return ErrorfL(wolLogger, "invalid broadcast IP address", fmt.Errorf("invalid IP: %s", broadcastIP))
}
target = broadcastIP
}
// Create the magic packet
packet := createMagicPacket(mac)
// Set up UDP connection
conn, err := net.Dial("udp", target+":9")
if err != nil {
wolErrors.Inc()
return ErrorfL(wolLogger, "failed to establish UDP connection", err)
}
defer conn.Close()
// Send the packet
_, err = conn.Write(packet)
if err != nil {
wolErrors.Inc()
return ErrorfL(wolLogger, "failed to send WOL packet", err)
}
wolLogger.Info().Str("mac", macAddress).Msg("WOL packet sent")
wolPackets.Inc()
return nil
}
// createMagicPacket creates a Wake-on-LAN magic packet
func createMagicPacket(mac net.HardwareAddr) []byte {
var buf bytes.Buffer
// Write 6 bytes of 0xFF
buf.Write(bytes.Repeat([]byte{0xFF}, 6))
// Write the target MAC address 16 times
for range 16 {
_ = binary.Write(&buf, binary.BigEndian, mac)
}
return buf.Bytes()
}