- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言: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
留言
張貼留言