targeting.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. "strings"
  6. )
  7. type TargetOptions int
  8. const (
  9. TargetGlobal = 1 << iota
  10. TargetContinent
  11. TargetCountry
  12. TargetRegionGroup
  13. TargetRegion
  14. TargetASN
  15. TargetIP
  16. )
  17. var cidr48Mask net.IPMask
  18. func init() {
  19. cidr48Mask = net.CIDRMask(48, 128)
  20. }
  21. func (t TargetOptions) GetTargets(ip net.IP) ([]string, int) {
  22. targets := make([]string, 0)
  23. var country, continent, region, regionGroup, asn string
  24. var netmask int
  25. if t&TargetASN > 0 {
  26. asn, netmask = geoIP.GetASN(ip)
  27. }
  28. if t&TargetRegion > 0 || t&TargetRegionGroup > 0 {
  29. country, continent, regionGroup, region, netmask = geoIP.GetCountryRegion(ip)
  30. } else if t&TargetCountry > 0 || t&TargetContinent > 0 {
  31. country, continent, netmask = geoIP.GetCountry(ip)
  32. }
  33. if t&TargetIP > 0 {
  34. ipStr := ip.String()
  35. targets = append(targets, "["+ipStr+"]")
  36. ip4 := ip.To4()
  37. if ip4 != nil {
  38. if ip4[3] != 0 {
  39. ip4[3] = 0
  40. targets = append(targets, "["+ip4.String()+"]")
  41. }
  42. } else {
  43. // v6 address, also target the /48 address
  44. ip48 := ip.Mask(cidr48Mask)
  45. targets = append(targets, "["+ip48.String()+"]")
  46. }
  47. }
  48. if t&TargetASN > 0 && len(asn) > 0 {
  49. targets = append(targets, asn)
  50. }
  51. if t&TargetRegion > 0 && len(region) > 0 {
  52. targets = append(targets, region)
  53. }
  54. if t&TargetRegionGroup > 0 && len(regionGroup) > 0 {
  55. targets = append(targets, regionGroup)
  56. }
  57. if t&TargetCountry > 0 && len(country) > 0 {
  58. targets = append(targets, country)
  59. }
  60. if t&TargetContinent > 0 && len(continent) > 0 {
  61. targets = append(targets, continent)
  62. }
  63. if t&TargetGlobal > 0 {
  64. targets = append(targets, "@")
  65. }
  66. return targets, netmask
  67. }
  68. func (t TargetOptions) String() string {
  69. targets := make([]string, 0)
  70. if t&TargetGlobal > 0 {
  71. targets = append(targets, "@")
  72. }
  73. if t&TargetContinent > 0 {
  74. targets = append(targets, "continent")
  75. }
  76. if t&TargetCountry > 0 {
  77. targets = append(targets, "country")
  78. }
  79. if t&TargetRegionGroup > 0 {
  80. targets = append(targets, "regiongroup")
  81. }
  82. if t&TargetRegion > 0 {
  83. targets = append(targets, "region")
  84. }
  85. if t&TargetASN > 0 {
  86. targets = append(targets, "asn")
  87. }
  88. if t&TargetIP > 0 {
  89. targets = append(targets, "ip")
  90. }
  91. return strings.Join(targets, " ")
  92. }
  93. func parseTargets(v string) (tgt TargetOptions, err error) {
  94. targets := strings.Split(v, " ")
  95. for _, t := range targets {
  96. var x TargetOptions
  97. switch t {
  98. case "@":
  99. x = TargetGlobal
  100. case "country":
  101. x = TargetCountry
  102. case "continent":
  103. x = TargetContinent
  104. case "regiongroup":
  105. x = TargetRegionGroup
  106. case "region":
  107. x = TargetRegion
  108. case "asn":
  109. x = TargetASN
  110. case "ip":
  111. x = TargetIP
  112. default:
  113. err = fmt.Errorf("Unknown targeting option '%s'", t)
  114. }
  115. tgt = tgt | x
  116. }
  117. return
  118. }