Ctrl K
ComunidadGuías…

magicpacket/magicpacket.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package magicpacket

import (
	"fmt"
	"io"
	"net"
)

const (
	// A magic packet is a 6-byte 0xFF sync stream followed by the MAC repeated 16 times.
	packetSize     = 102
	syncStreamSize = 6
	macRepeatCount = 16
)

// MagicPacket represents a wake-on-LAN packet
type MagicPacket struct {
	// The MAC address of the machine to wake up
	MacAddress net.HardwareAddr
}

// NewMagicPacket creates a new MagicPacket for the given MAC address
func NewMagicPacket(macAddress net.HardwareAddr) *MagicPacket {
	return &MagicPacket{MacAddress: macAddress}
}

// Bytes returns the raw magic packet payload.
func (p *MagicPacket) Bytes() []byte {
	packet := make([]byte, packetSize)
	for i := 0; i < syncStreamSize; i++ {
		packet[i] = 0xFF
	}
	for i := 1; i <= macRepeatCount; i++ {
		copy(packet[i*6:], p.MacAddress)
	}
	return packet
}

// WriteTo writes the packet to w. It implements io.WriterTo so the send path can
// be tested against an in-memory writer instead of the network.
func (p *MagicPacket) WriteTo(w io.Writer) (int64, error) {
	n, err := w.Write(p.Bytes())
	return int64(n), err
}

// Broadcast sends the magic packet to addr, a "host:port" broadcast target such
// as "255.255.255.255:9" or a subnet-directed broadcast like "192.168.1.255:9".
// A subnet-directed broadcast is routed out the interface owning that subnet,
// which is what makes waking devices reliable on multi-homed hosts.
func (p *MagicPacket) Broadcast(addr string) (err error) {
	udpAddr, err := net.ResolveUDPAddr("udp", addr)
	if err != nil {
		return fmt.Errorf("invalid broadcast address %q: %w", addr, err)
	}
	conn, err := net.DialUDP("udp", nil, udpAddr)
	if err != nil {
		return err
	}
	// Surface a close error, but don't let it mask a write error.
	defer func() {
		if cerr := conn.Close(); cerr != nil && err == nil {
			err = cerr
		}
	}()

	_, err = p.WriteTo(conn)
	return err
}