Skip to content

Instantly share code, notes, and snippets.

@chriskillpack
Created December 4, 2016 23:57
Show Gist options
  • Save chriskillpack/bc53c34808e24ff1a9b5913ca9b9fc55 to your computer and use it in GitHub Desktop.
Save chriskillpack/bc53c34808e24ff1a9b5913ca9b9fc55 to your computer and use it in GitHub Desktop.
Broadcast Wake on LAN packet
// Broadcast Wake On LAN packet, see https://en.wikipedia.org/wiki/Wake-on-LAN#Magic_packet
package main
import (
"fmt"
"log"
"net"
"os"
"strings"
"time"
)
var (
// Wake-on-LAN packet body preamble
wolPreamble = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
)
// Supports either - or : separators
func parseMacArg(mac string) ([]byte, error) {
m := strings.Replace(mac, "-", ":", -1)
a := make([]byte, 6)
n, err := fmt.Sscanf(m, "%2x:%2x:%2x:%2x:%2x:%2x", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5])
if n < 6 || err != nil {
return nil, err
}
return a, nil
}
func main() {
log.SetFlags(0)
args := os.Args[1:]
if len(args) < 1 {
log.Fatal("No MAC address provided")
}
targetMAC, err := parseMacArg(args[0])
if err != nil {
log.Fatal(err)
}
// Assemble the magic packet
packet := make([]byte, 0, 102)
packet = append(packet, wolPreamble...)
for i := 0; i < 16; i++ {
packet = append(packet, targetMAC...)
}
// Broadcast packet to all 3 ports just to be sure
// OS X will not allow a connection to port 0
for _, port := range []int{0, 7, 9} {
conn, err := net.DialUDP("udp4", nil, &net.UDPAddr{
IP: net.IPv4bcast,
Port: port,
})
if err != nil {
log.Printf("Error opening UDP: %v\n", err)
continue
}
defer conn.Close()
// Write the packet
n, err := conn.Write(packet)
if err != nil {
log.Fatalf("Failed to send packet: %v\n", err)
}
if n != 102 {
fmt.Printf("Expected to send 102 bytes, sent %d", n)
}
<-time.After(250 * time.Millisecond)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment