packet.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package firewall
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/netip"
  6. )
  7. type m = map[string]any
  8. const (
  9. ProtoAny = 0 // When we want to handle HOPOPT (0) we can change this, if ever
  10. ProtoTCP = 6
  11. ProtoUDP = 17
  12. ProtoICMP = 1
  13. ProtoICMPv6 = 58
  14. PortAny = 0 // Special value for matching `port: any`
  15. PortFragment = -1 // Special value for matching `port: fragment`
  16. )
  17. type Packet struct {
  18. LocalAddr netip.Addr
  19. RemoteAddr netip.Addr
  20. // LocalPort is the destination port for incoming traffic, or the source port for outgoing. Zero for ICMP.
  21. LocalPort uint16
  22. // RemotePort is the source port for incoming traffic, or the destination port for outgoing.
  23. // For ICMP, it's the "identifier". This is only used for connection tracking, actual firewall rules will not filter on ICMP identifier
  24. RemotePort uint16
  25. Protocol uint8
  26. Fragment bool
  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 ProtoTCP:
  42. proto = "tcp"
  43. case ProtoICMP:
  44. proto = "icmp"
  45. case ProtoICMPv6:
  46. proto = "icmpv6"
  47. case ProtoUDP:
  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. }