wails-app-dock/pkg/server/services/wol/wol.go
2024-02-17 21:45:43 +08:00

88 lines
1.6 KiB
Go

package wol
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"net"
"regexp"
"strings"
)
var (
MacFormatError = errors.New("mac 地址格式错误")
)
type Service struct {
}
var Services *Service
func init() {
Services = &Service{}
}
func (s *Service) validateMac(mac string) bool {
exp, _ := regexp.Compile("([0-9a-fA-F]{2}(-|:)?){5}([a-fA-F0-9]{2})")
macLen := len(mac)
return exp.MatchString(mac) && (macLen == 12 || macLen == 17)
}
func (s *Service) WakeUp(mac string, port int) error {
mac = strings.Replace(strings.Replace(mac, ":", "", -1), "-", "", -1)
if !s.validateMac(mac) {
return MacFormatError
}
return s.wake(mac, port)
}
func (s *Service) wake(mac string, port int) error {
udpAddr, _ := net.ResolveUDPAddr("udp", fmt.Sprintf("255.255.255.255:%d", port))
interfaces, err := net.Interfaces()
if err != nil {
return err
}
macHex, _ := hex.DecodeString(mac)
// 广播MAC地址 FF:FF:FF:FF:FF:FF
var broadcast = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
var buffer bytes.Buffer
buffer.Write(broadcast)
for i := 0; i < 16; i++ {
buffer.Write(macHex)
}
wolPackage := buffer.Bytes()
for _, i := range interfaces {
if i.Flags&net.FlagUp == 0 {
continue
}
addrs, err := i.Addrs()
if err != nil {
return err
}
for _, addr := range addrs {
if ip, ok := addr.(*net.IPNet); ok {
if ipv4 := ip.IP.To4(); ipv4 != nil {
conn, err := net.DialUDP("udp", &net.UDPAddr{IP: ipv4}, udpAddr)
if err != nil {
return err
}
_, _ = conn.Write(wolPackage)
_ = conn.Close()
}
}
}
}
return err
}