pcap.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package disco
  4. import (
  5. "bytes"
  6. "encoding/binary"
  7. "net/netip"
  8. "tailscale.com/tailcfg"
  9. "tailscale.com/types/key"
  10. )
  11. // ToPCAPFrame marshals the bytes for a pcap record that describe a disco frame.
  12. //
  13. // Warning: Alloc garbage. Acceptable while capturing.
  14. func ToPCAPFrame(src netip.AddrPort, derpNodeSrc key.NodePublic, payload []byte) []byte {
  15. var (
  16. b bytes.Buffer
  17. flag uint8
  18. )
  19. b.Grow(128) // Most disco frames will probably be smaller than this.
  20. if src.Addr() == tailcfg.DerpMagicIPAddr {
  21. flag |= 0x01
  22. }
  23. b.WriteByte(flag) // 1b: flag
  24. derpSrc := derpNodeSrc.Raw32()
  25. b.Write(derpSrc[:]) // 32b: derp public key
  26. binary.Write(&b, binary.LittleEndian, uint16(src.Port())) // 2b: port
  27. addr, _ := src.Addr().MarshalBinary()
  28. binary.Write(&b, binary.LittleEndian, uint16(len(addr))) // 2b: len(addr)
  29. b.Write(addr) // Xb: addr
  30. binary.Write(&b, binary.LittleEndian, uint16(len(payload))) // 2b: len(payload)
  31. b.Write(payload) // Xb: payload
  32. return b.Bytes()
  33. }