package icmp import ( "bytes" "encoding/binary" "net" "time" "golang.org/x/net/icmp" ) func netAddrToIPAddr(a net.Addr) *net.IPAddr { switch v := a.(type) { case *net.UDPAddr: return &net.IPAddr{IP: v.IP, Zone: v.Zone} case *net.IPAddr: return v } return nil } func (pkt *Packet) BuildEchoRequestMessage(icmptype Type) ([]byte, error) { if pkt.Nbytes < 48 { pkt.Nbytes = 48 } if pkt.Nbytes > 8192 { pkt.Nbytes = 8192 } bs := bytes.Repeat([]byte{1}, pkt.Nbytes-8) pkt.SendTime = time.Now() binary.BigEndian.PutUint64(bs, uint64(pkt.SendTime.UnixNano())) binary.BigEndian.PutUint64(bs[8:], uint64(pkt.Seq)) binary.BigEndian.PutUint64(bs[16:], uint64(pkt.ID)) copy(bs[24:], pkt.UUID[:]) body := &icmp.Echo{ ID: pkt.ID % 65536, // 2 bytes Seq: pkt.Seq % 65536, // 2 bytes Data: bs, } msg := &icmp.Message{ Type: icmptype, // 1 byte Code: 0, // 1 byte, Checksum 2 bytes Body: body, } msgBytes, err := msg.Marshal(nil) if err != nil { return nil, err } return msgBytes, nil }