1
0

packet.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. }