header.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package packet
  4. import (
  5. "errors"
  6. "math"
  7. )
  8. const igmpHeaderLength = 8
  9. const tcpHeaderLength = 20
  10. const sctpHeaderLength = 12
  11. // maxPacketLength is the largest length that all headers support.
  12. // IPv4 headers using uint16 for this forces an upper bound of 64KB.
  13. const maxPacketLength = math.MaxUint16
  14. var (
  15. // errSmallBuffer is returned when Marshal receives a buffer
  16. // too small to contain the header to marshal.
  17. errSmallBuffer = errors.New("buffer too small")
  18. // errLargePacket is returned when Marshal receives a payload
  19. // larger than the maximum representable size in header
  20. // fields.
  21. errLargePacket = errors.New("packet too large")
  22. )
  23. // Header is a packet header capable of marshaling itself into a byte
  24. // buffer.
  25. type Header interface {
  26. // Len returns the length of the marshaled packet.
  27. Len() int
  28. // Marshal serializes the header into buf, which must be at
  29. // least Len() bytes long. Implementations of Marshal assume
  30. // that bytes after the first Len() are payload bytes for the
  31. // purpose of computing length and checksum fields. Marshal
  32. // implementations must not allocate memory.
  33. Marshal(buf []byte) error
  34. }
  35. // HeaderChecksummer is implemented by Header implementations that
  36. // need to do a checksum over their payloads.
  37. type HeaderChecksummer interface {
  38. Header
  39. // WriteCheck writes the correct checksum into buf, which should
  40. // be be the already-marshalled header and payload.
  41. WriteChecksum(buf []byte)
  42. }
  43. // Generate generates a new packet with the given Header and
  44. // payload. This function allocates memory, see Header.Marshal for an
  45. // allocation-free option.
  46. func Generate(h Header, payload []byte) []byte {
  47. hlen := h.Len()
  48. buf := make([]byte, hlen+len(payload))
  49. copy(buf[hlen:], payload)
  50. h.Marshal(buf)
  51. if hc, ok := h.(HeaderChecksummer); ok {
  52. hc.WriteChecksum(buf)
  53. }
  54. return buf
  55. }