feat(sol): UDP + HTTP listener
This commit is contained in:
89
magicpacket/magicpacket.go
Normal file
89
magicpacket/magicpacket.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user