utils.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package icmp
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "net"
  6. "time"
  7. "golang.org/x/net/icmp"
  8. )
  9. func netAddrToIPAddr(a net.Addr) *net.IPAddr {
  10. switch v := a.(type) {
  11. case *net.UDPAddr:
  12. return &net.IPAddr{IP: v.IP, Zone: v.Zone}
  13. case *net.IPAddr:
  14. return v
  15. }
  16. return nil
  17. }
  18. func (pkt *Packet) BuildEchoRequestMessage(icmptype Type) ([]byte, error) {
  19. if pkt.Nbytes < 48 {
  20. pkt.Nbytes = 48
  21. }
  22. if pkt.Nbytes > 8192 {
  23. pkt.Nbytes = 8192
  24. }
  25. bs := bytes.Repeat([]byte{1}, pkt.Nbytes-8)
  26. pkt.SendTime = time.Now()
  27. binary.BigEndian.PutUint64(bs, uint64(pkt.SendTime.UnixNano()))
  28. binary.BigEndian.PutUint64(bs[8:], uint64(pkt.Seq))
  29. binary.BigEndian.PutUint64(bs[16:], uint64(pkt.ID))
  30. copy(bs[24:], pkt.UUID[:])
  31. body := &icmp.Echo{
  32. ID: pkt.ID % 65536, // 2 bytes
  33. Seq: pkt.Seq % 65536, // 2 bytes
  34. Data: bs,
  35. }
  36. msg := &icmp.Message{
  37. Type: icmptype, // 1 byte
  38. Code: 0, // 1 byte, Checksum 2 bytes
  39. Body: body,
  40. }
  41. msgBytes, err := msg.Marshal(nil)
  42. if err != nil {
  43. return nil, err
  44. }
  45. return msgBytes, nil
  46. }