feat(sol): UDP + HTTP listener

This commit is contained in:
Björn Benouarets
2025-11-11 17:19:49 +01:00
commit 8ed56f7ba0
12 changed files with 565 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
package magicpacket
import (
"bytes"
"strings"
)
const (
// Magic packet format: 6 bytes of 0xFF followed by 16 repetitions of the MAC address
MagicPacketHeader = 6
MacAddressRepetitions = 16
MacAddressLength = 6
// Authentication format for UDP: "AUTH:username:password:" followed by magic packet
AuthPrefix = "AUTH:"
)
// IsMagicPacket checks if the received data is a valid Wake-on-LAN Magic Packet
// Format: 6 bytes of 0xFF followed by 16 repetitions of the MAC address (6 bytes each)
func IsMagicPacket(data []byte) bool {
// Minimum size: 6 (header) + 16*6 (MAC repetitions) = 102 bytes
minSize := MagicPacketHeader + (MacAddressRepetitions * MacAddressLength)
if len(data) < minSize {
return false
}
// Check for 6 bytes of 0xFF at the beginning
header := data[:MagicPacketHeader]
for _, b := range header {
if b != 0xFF {
return false
}
}
// Extract the MAC address (first 6 bytes after header)
macAddr := data[MagicPacketHeader : MagicPacketHeader+MacAddressLength]
// Check if the MAC address is repeated 16 times
for i := 1; i < MacAddressRepetitions; i++ {
offset := MagicPacketHeader + (i * MacAddressLength)
if offset+MacAddressLength > len(data) {
return false
}
repeatedMac := data[offset : offset+MacAddressLength]
if !bytes.Equal(macAddr, repeatedMac) {
return false
}
}
return true
}
// ExtractAuthFromPacket extracts username and password from an authenticated packet
// Format: "AUTH:username:password:" followed by standard magic packet
// Returns username, password, magicPacketData, and success status
func ExtractAuthFromPacket(data []byte) (string, string, []byte, bool) {
dataStr := string(data)
// Check for authentication prefix
if !strings.HasPrefix(dataStr, AuthPrefix) {
return "", "", nil, false
}
// Extract authentication part
authEnd := strings.Index(dataStr[len(AuthPrefix):], ":")
if authEnd == -1 {
return "", "", nil, false
}
authEnd += len(AuthPrefix)
// Extract username and password
authPart := dataStr[len(AuthPrefix):authEnd]
parts := strings.Split(authPart, ":")
if len(parts) != 2 {
return "", "", nil, false
}
username := parts[0]
password := parts[1]
// Extract magic packet part (after "AUTH:username:password:")
magicPacketStart := authEnd + 1
if magicPacketStart >= len(data) {
return "", "", nil, false
}
magicPacketData := data[magicPacketStart:]
return username, password, magicPacketData, true
}