packet.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package firewall
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/netip"
  6. "github.com/slackhq/nebula/iputil"
  7. )
  8. type m = map[string]any
  9. const (
  10. ProtoAny = 0 // When we want to handle HOPOPT (0) we can change this, if ever
  11. PortAny = 0 // Special value for matching `port: any`
  12. PortFragment = -1 // Special value for matching `port: fragment`
  13. )
  14. type Packet struct {
  15. LocalAddr netip.Addr
  16. RemoteAddr netip.Addr
  17. // LocalPort is the destination port for incoming traffic, or the source port for outgoing. Zero for ICMP.
  18. LocalPort uint16
  19. // RemotePort is the source port for incoming traffic, or the destination port for outgoing.
  20. // For ICMP, it's the "identifier". This is only used for connection tracking, actual firewall rules will not filter on ICMP identifier
  21. RemotePort uint16
  22. Protocol uint8
  23. Fragment bool
  24. // pad fills what would otherwise be compiler padding. A Packet with no padding hashes as one
  25. // block of memory, which makes it a much faster map key. Always zero.
  26. pad [2]byte
  27. }
  28. func (fp *Packet) Copy() *Packet {
  29. return &Packet{
  30. LocalAddr: fp.LocalAddr,
  31. RemoteAddr: fp.RemoteAddr,
  32. LocalPort: fp.LocalPort,
  33. RemotePort: fp.RemotePort,
  34. Protocol: fp.Protocol,
  35. Fragment: fp.Fragment,
  36. }
  37. }
  38. func (fp Packet) MarshalJSON() ([]byte, error) {
  39. var proto string
  40. switch fp.Protocol {
  41. case iputil.IPProtocolTCP:
  42. proto = "tcp"
  43. case iputil.IPProtocolICMP:
  44. proto = "icmp"
  45. case iputil.IPProtocolICMPv6:
  46. proto = "icmpv6"
  47. case iputil.IPProtocolUDP:
  48. proto = "udp"
  49. default:
  50. proto = fmt.Sprintf("unknown %v", fp.Protocol)
  51. }
  52. return json.Marshal(m{
  53. "LocalAddr": fp.LocalAddr.String(),
  54. "RemoteAddr": fp.RemoteAddr.String(),
  55. "LocalPort": fp.LocalPort,
  56. "RemotePort": fp.RemotePort,
  57. "Protocol": proto,
  58. "Fragment": fp.Fragment,
  59. })
  60. }
  61. // ParsedPacket is a Packet plus the parse byproducts the RX path reuses
  62. type ParsedPacket struct {
  63. Packet
  64. IPHdrLen int
  65. // FragAny reports any fragmentation at all: MF flag or nonzero offset for IPv4, a fragment extension header for IPv6.
  66. // Distinct from Packet.Fragment, which is true only for NON-FIRST fragments
  67. FragAny bool
  68. }