flowclass.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package flowclass
  2. import (
  3. "fmt"
  4. "idio.link/go/netaddr/v2"
  5. "idio.link/go/parser"
  6. )
  7. type FlowClass struct {
  8. // dstClasses indices correspond to ipps indices
  9. tree *parser.CSTNode
  10. srcs []*netaddr.NetAddr
  11. dsts [][]*netaddr.NetAddr
  12. ipps [][]IPP
  13. }
  14. func (fc *FlowClass) Compile(s string) error {
  15. err := fc.tree.Parse(s)
  16. if err != nil {
  17. return err
  18. }
  19. coalesced := fc.tree.Coalesce()
  20. fc.srcs = coalesced.srcs.(map[string]*netaddr.NetAddr)
  21. fc.dsts = coalesced.dsts.([]*DstSock)
  22. fc.tree = nil
  23. return nil
  24. }
  25. func (fc *FlowClass) Sources() []*netaddr.NetAddr {
  26. srcs := make([]*netaddr.NetAddr, len(fc.srcs))
  27. for i, e := range fc.srcs {
  28. tmp := *e
  29. srcs[i] = &tmp
  30. }
  31. return srcs
  32. }
  33. func (fc *FlowClass) Destinations() []*netaddr.NetAddr {
  34. dsts := make([]*netaddr.NetAddr, len(fc.dsts))
  35. for i, e := range fc.dstSocks {
  36. tmp := *e
  37. dsts[i] = &tmp
  38. }
  39. return dsts
  40. }
  41. type IPP interface {
  42. Name() string
  43. Decimal() ipProtocol
  44. String() string
  45. }
  46. /* If this is used to indicate ICMP with type of "any", how
  47. * do we represent this in port literals?
  48. */
  49. type ipProtocol byte
  50. func (p ipProtocol) Name() string {
  51. return ""
  52. }
  53. func (p ipProtocol) String() string {
  54. return fmt.Sprintf("%d", p)
  55. }
  56. func (p ipProtocol) Decimal() ipProtocol {
  57. return p
  58. }
  59. type ippICMP struct {
  60. icmpType byte
  61. code byte
  62. }
  63. func (p ippICMP) Type() byte {
  64. return p.icmpType
  65. }
  66. func (p ippICMP) Code() byte {
  67. return p.code
  68. }
  69. func (p ippICMP) Name() string {
  70. return "icmp"
  71. }
  72. func (p ippICMP) Decimal() ipProtocol {
  73. return 1
  74. }
  75. func (p ippICMP) String() string {
  76. return fmt.Sprintf("%s(%d,%d)", p.Name(), p.Type(), p.Code())
  77. }
  78. type ippTCP struct {
  79. spt uint16
  80. dpt uint16
  81. }
  82. func (p ippTCP) Sport() uint16 {
  83. return p.spt
  84. }
  85. func (p ippTCP) Dport() uint16 {
  86. return p.dpt
  87. }
  88. func (p ippTCP) Name() string {
  89. return "tcp"
  90. }
  91. func (p ippTCP) Decimal() ipProtocol {
  92. return 6
  93. }
  94. func (p ippTCP) String() string {
  95. return fmt.Sprintf("%s(%d,%d)", p.Name(), p.Sport(), p.Dport())
  96. }
  97. type ippUDP struct {
  98. spt uint16
  99. dpt uint16
  100. }
  101. func (p ippUDP) Sport() uint16 {
  102. return p.spt
  103. }
  104. func (p ippUDP) Dport() uint16 {
  105. return p.dpt
  106. }
  107. func (p ippUDP) Name() string {
  108. return "udp"
  109. }
  110. func (p ippUDP) Decimal() ipProtocol {
  111. return 17
  112. }
  113. func (p ippUDP) String() string {
  114. return fmt.Sprintf("%s(%d,%d)", p.Name(), p.Sport(), p.Dport())
  115. }