- 取得連結
- 以電子郵件傳送
- 其他應用程式
程式語言:Go
功能:建立魔法封包
由於只要資料是以上格式即可,因此可以作為任何網絡和傳輸層協議發送
通常做法為 UDP 發送到端口 0, 7, 9 之一
TCP 不太適合,因目標通常為待機狀態,無法進行 Handshake 的動作
github.com/linde12/gowol
github.com/ghthor/gowol
github.com/sabhiram/go-wol
- Package:
- "bytes"
- "encoding/binary"
- "fmt"
- "log"
- "net"
- "regexp"
- "github.com/pkg/errors"
功能:建立魔法封包
格式說明
魔術封包 包含 6 bytes 的 0xFF 與 16 次重複的 MAC 地址由於只要資料是以上格式即可,因此可以作為任何網絡和傳輸層協議發送
通常做法為 UDP 發送到端口 0, 7, 9 之一
TCP 不太適合,因目標通常為待機狀態,無法進行 Handshake 的動作
程式碼
magicPacket.go
magicPacket_test.go
package magicPacket //////////////////////////////////////////////////////////////////////////////// import ( "bytes" "encoding/binary" "fmt" "log" "net" "regexp" "github.com/pkg/errors" ) //////////////////////////////////////////////////////////////////////////////// var ( delims = ":-" reMAC = regexp.MustCompile(`^([0-9a-fA-F]{2}[` + delims + `]){5}([0-9a-fA-F]{2})$`) ) //////////////////////////////////////////////////////////////////////////////// // MACAddress represents a 6 byte network mac address. type MACAddress [6]byte // A MagicPacket is constituted of 6 bytes of 0xFF followed by 16-groups of the // destination MAC address. type MagicPacket struct { header [6]byte payload [16]MACAddress } // New returns a magic packet based on a mac address string. func New(mac string) (*MagicPacket, error) { var packet MagicPacket var macAddr MACAddress hwAddr, err := net.ParseMAC(mac) if err != nil { return nil, errors.Wrap(err, "net.ParseMAC") } // We only support 6 byte MAC addresses since it is much harder to use the // binary.Write(...) interface when the size of the MagicPacket is dynamic. if !reMAC.MatchString(mac) { return nil, errors.Errorf("%s is not a IEEE 802 MAC-48 address", mac) } // Copy bytes from the returned HardwareAddr -> a fixed size MACAddress. for idx := range macAddr { macAddr[idx] = hwAddr[idx] } // Setup the header which is 6 repetitions of 0xFF. for idx := range packet.header { packet.header[idx] = 0xFF } // Setup the payload which is 16 repetitions of the MAC addr. for idx := range packet.payload { packet.payload[idx] = macAddr } return &packet, nil } // Marshal serializes the magic packet structure into a 102 byte slice. func (mp *MagicPacket) marshal() ([]byte, error) { var buf bytes.Buffer if err := binary.Write(&buf, binary.BigEndian, mp); err != nil { return nil, err } return buf.Bytes(), nil } // Send MagicPacket by UDP func (mp *MagicPacket) SendUDP(ip string, port int) error { bcastAddr := fmt.Sprintf("%s:%d", ip, port) udpAddr, err := net.ResolveUDPAddr("udp", bcastAddr) if err != nil { return errors.Wrap(err, "net.ResolveUDPAddr") } conn, err := net.DialUDP("udp", nil, udpAddr) if err != nil { return errors.Wrap(err, "net.DialUDP") } defer conn.Close() log.Printf("Attempting to send a magic packet to MAC %x\n", mp.payload[0]) log.Printf("... Broadcasting to: %s\n", bcastAddr) bs, err := mp.marshal() if err != nil { return errors.Wrap(err, "mp.marshal") } _, err = conn.Write(bs) return errors.Wrap(err, "conn.Write") }
magicPacket_test.go
package magicPacket import ( "testing" ) func TestSendUDP(t *testing.T) { mp, err := New("11:22:33:44:55:66") if err != nil { t.Error(err) } err = mp.SendUDP("192.168.1.255", 9) if err != nil { t.Error(err) } }
參考
Wake-on-LANgithub.com/linde12/gowol
github.com/ghthor/gowol
github.com/sabhiram/go-wol
留言
張貼留言