geoip.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package geoip
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. gg "github.com/oschwald/geoip2-golang"
  7. )
  8. type Anonymous struct {
  9. // from geoip2-golang.AnonymousIP
  10. IsAnonymous bool `json:"is_anonymous"`
  11. IsAnonymousVPN bool `json:"is_anonymous_vpn"`
  12. IsHostingProvider bool `json:"is_hosting_provider"`
  13. IsPublicProxy bool `json:"is_public_proxy"`
  14. IsTorExitNode bool `json:"is_tor_exit_node"`
  15. }
  16. type City struct {
  17. Name string `json:"name"`
  18. Continent string `json:"continent"`
  19. ContinentCode string `json:"continent_code"`
  20. Country string `json:"country"`
  21. CountryCode string `json:"country_code"`
  22. AccuracyRadius uint16 `json:"accuracy_radius"`
  23. Latitude float64 `json:"latitude"`
  24. Longitude float64 `json:"longitude"`
  25. MetroCode uint `json:"metro_code"`
  26. Timezone string `json:"timezone"`
  27. Postcode string `json:"postcode"`
  28. RegisteredCountry string `json:"registered_country"`
  29. RegisteredCountryCode string `json:"registered_country_code"`
  30. RepresentedCountry string `json:"represented_country"`
  31. RepresentedCountryCode string `json:"represented_country_code"`
  32. RepresentedCountryType string `json:"represented_country_type"`
  33. Subdivisions []string `json:"subdivisions"`
  34. IsAnonymousProxy bool `json:"is_anonymous_proxy"`
  35. IsSatelliteProvider bool `json:"is_satellite_provider"`
  36. }
  37. type ConnectionType struct {
  38. Type string `json:"connection_type"`
  39. }
  40. type Country struct {
  41. ContinentCode string `json:"continent_code"`
  42. Continent string `json:"continent"`
  43. CountryCode string `json:"country_code"`
  44. Country string `json:"country"`
  45. RegisteredCountryCode string `json:"registered_country_code"`
  46. RegisteredCountry string `json:"registered_country"`
  47. RepresentedCountryCode string `json:"represented_country_code"`
  48. RepresentedCountryType string `json:"represented_country_type"`
  49. RepresentedCountry string `json:"represented_country"`
  50. IsAnonymousProxy bool `json:"is_anonymous_proxy"`
  51. IsSatelliteProvider bool `json:"is_satellite_provider"`
  52. }
  53. type Domain struct {
  54. Domain string `json:"domain"`
  55. }
  56. type ISP struct {
  57. AutonomousSystemNumber uint `json:"autonomous_system_number"`
  58. AutonomousSystemOrganization string `json:"autonomous_system_organization"`
  59. ISP string `json:"isp"`
  60. Organization string `json:"organization"`
  61. }
  62. type GeoIP struct {
  63. db *gg.Reader `json:"-"`
  64. IP net.IP `json:"ip"`
  65. Anonymous *Anonymous `json:"anonymous"`
  66. City *City `json:"city"`
  67. Country *Country `json:"country"`
  68. Domain *Domain `json:"domain"`
  69. ISP *ISP `json:"isp"`
  70. }
  71. func NewGeoIP(dbpath string) (*GeoIP, error) {
  72. ggReader, err := gg.Open(dbpath)
  73. if err != nil {
  74. return nil, err
  75. }
  76. g := GeoIP{
  77. db: ggReader,
  78. }
  79. return &g, nil
  80. }
  81. func (g *GeoIP) Close() {
  82. g.db.Close()
  83. }
  84. func (g *GeoIP) Lookup(ipAddr string) error {
  85. g.IP = net.ParseIP(ipAddr)
  86. if g.IP == nil {
  87. return errors.New(fmt.Sprintf("%s is not a valid IP address!", ipAddr))
  88. }
  89. // ANONYMOUS IP
  90. //
  91. anon, err := g.db.AnonymousIP(g.IP)
  92. if err == nil {
  93. g.Anonymous = &Anonymous{}
  94. g.Anonymous.IsAnonymous = anon.IsAnonymous
  95. g.Anonymous.IsAnonymousVPN = anon.IsAnonymousVPN
  96. g.Anonymous.IsHostingProvider = anon.IsHostingProvider
  97. g.Anonymous.IsPublicProxy = anon.IsPublicProxy
  98. g.Anonymous.IsTorExitNode = anon.IsTorExitNode
  99. } else {
  100. g.Anonymous = nil
  101. }
  102. // CITY
  103. //
  104. city, err := g.db.City(g.IP)
  105. if err == nil {
  106. g.City = &City{}
  107. g.City.AccuracyRadius = city.Location.AccuracyRadius
  108. g.City.Continent = city.Continent.Names["en"]
  109. g.City.ContinentCode = city.Continent.Code
  110. g.City.Country = city.Country.Names["en"]
  111. g.City.CountryCode = city.Country.IsoCode
  112. g.City.IsAnonymousProxy = city.Traits.IsAnonymousProxy
  113. g.City.IsSatelliteProvider = city.Traits.IsSatelliteProvider
  114. g.City.Latitude = city.Location.Latitude
  115. g.City.Longitude = city.Location.Longitude
  116. g.City.MetroCode = city.Location.MetroCode
  117. g.City.Name = city.City.Names["en"]
  118. g.City.Postcode = city.Postal.Code
  119. g.City.RegisteredCountry = city.RegisteredCountry.Names["en"]
  120. g.City.RegisteredCountryCode = city.RegisteredCountry.IsoCode
  121. g.City.RepresentedCountry = city.RepresentedCountry.Names["en"]
  122. g.City.RepresentedCountryCode = city.RepresentedCountry.IsoCode
  123. g.City.RepresentedCountryType = city.RepresentedCountry.Type
  124. subdivisions := make([]string, len(city.Subdivisions), len(city.Subdivisions))
  125. for i, sd := range city.Subdivisions {
  126. subdivisions[i] = sd.Names["en"]
  127. }
  128. g.City.Subdivisions = subdivisions
  129. g.City.Timezone = city.Location.TimeZone
  130. } else {
  131. g.City = nil
  132. }
  133. // COUNTRY
  134. //
  135. country, err := g.db.Country(g.IP)
  136. if err == nil {
  137. g.Country = &Country{}
  138. g.Country.Continent = country.Continent.Names["en"]
  139. g.Country.ContinentCode = country.Continent.Code
  140. g.Country.Country = country.Country.Names["en"]
  141. g.Country.CountryCode = country.Country.IsoCode
  142. g.Country.IsAnonymousProxy = country.Traits.IsAnonymousProxy
  143. g.Country.IsSatelliteProvider = country.Traits.IsSatelliteProvider
  144. g.Country.RegisteredCountry = country.RegisteredCountry.Names["en"]
  145. g.Country.RegisteredCountryCode = country.RegisteredCountry.IsoCode
  146. g.Country.RepresentedCountry = country.RepresentedCountry.Names["en"]
  147. g.Country.RepresentedCountryCode = country.RepresentedCountry.IsoCode
  148. g.Country.RepresentedCountryType = country.RepresentedCountry.Type
  149. } else {
  150. g.Country = nil
  151. }
  152. // DOMAIN
  153. //
  154. domain, err := g.db.Domain(g.IP)
  155. if err == nil {
  156. g.Domain = &Domain{}
  157. g.Domain.Domain = domain.Domain
  158. } else {
  159. g.Domain = nil
  160. }
  161. // ISP
  162. //
  163. isp, err := g.db.ISP(g.IP)
  164. if err == nil {
  165. g.ISP = &ISP{}
  166. g.ISP.AutonomousSystemNumber = isp.AutonomousSystemNumber
  167. g.ISP.AutonomousSystemOrganization = isp.AutonomousSystemOrganization
  168. g.ISP.ISP = isp.ISP
  169. g.ISP.Organization = isp.Organization
  170. } else {
  171. g.ISP = nil
  172. }
  173. return nil
  174. }