grs.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package grs
  2. import (
  3. "errors"
  4. "fmt"
  5. "gopkg.in/jmcvetta/napping.v3"
  6. "net"
  7. "net/url"
  8. "regexp"
  9. )
  10. const (
  11. GRS_URL = "http://rest.db.ripe.net/search.json"
  12. )
  13. type GRS struct {
  14. // ID bson.ObjectId `bson:"_id"`
  15. Source string `bson:"source" json:"source"`
  16. IpFrom string `bson:"ip_from" json:"ip_from"`
  17. IpTo string `bson:"ip_to" json:"ip_to"`
  18. IpFromRaw []byte `bson:"ip_from_raw" json:"ip_from_raw"`
  19. IpToRaw []byte `bson:"ip_to_raw" json:"ip_to_raw"`
  20. Description string `bson:"description" json:"description"`
  21. Country string `bson:"country" json:"country"`
  22. Status string `bson:"status" json:"status"`
  23. Cidr string `bson:"cidr" json:"cidr"`
  24. Name string `bson:"name" json:"name"`
  25. Org string `bson:"org" json:"org"`
  26. }
  27. type GRSRaw struct {
  28. Service Name `json:"service"`
  29. Parameters Parameters `json:"parameters"`
  30. Objects Objects `json:"objects"`
  31. Terms Terms `json:"terms-and-conditions"`
  32. ErrorMessages ErrorMessages `json:"errormessages"`
  33. }
  34. type Name struct {
  35. Name string `json:"name"`
  36. }
  37. type Parameters struct {
  38. InverseLookup map[string]interface{} `json:"inverse-lookup"`
  39. TypeFilters map[string]interface{} `json:"type-filters"`
  40. Flags map[string]interface{} `json:"flags"`
  41. QueryStrings QueryString `json:"query-strings"`
  42. Sources Sources `json:"sources"`
  43. }
  44. type QueryString struct {
  45. QueryString []Value `json:"query-string"`
  46. }
  47. type Value struct {
  48. Value string `json:"value"`
  49. }
  50. type Sources struct {
  51. Ids []Id `json:"source"`
  52. }
  53. type Id struct {
  54. ID string `json:"id"`
  55. }
  56. type Objects struct {
  57. Objects []Object `json:"object"`
  58. }
  59. type Object struct {
  60. Type string `json:"type"`
  61. Link Link `json:"link"`
  62. Source Id `json:source"`
  63. PrimaryKey Attributes `json:"primary-key"`
  64. Attributes Attributes `json:"attributes"`
  65. Tags Tags `json:"tags"`
  66. }
  67. type Link struct {
  68. Type string `json:"type"`
  69. Href string `json:"href"`
  70. }
  71. type Attributes struct {
  72. Attributes []Attribute `json:"attribute"`
  73. }
  74. type Attribute struct {
  75. Link Link `json:"link"`
  76. Name string `json:"name"`
  77. Value string `json:"value"`
  78. ReferencedType string `json:"referenced-type"`
  79. }
  80. type Tags struct {
  81. Tags []Tag `json:"tag"`
  82. }
  83. type Tag struct {
  84. ID string `json:"id"`
  85. Data string `json:"data"`
  86. }
  87. type Terms struct {
  88. Type string `json:"type"`
  89. Href string `json:"href"`
  90. }
  91. type ErrorMessages struct {
  92. ErrorMessage []ErrorMessage `json:"errormessage"`
  93. }
  94. type ErrorMessage struct {
  95. Severity string `json:"severity"`
  96. Text string `json:"text"`
  97. }
  98. func Lookup(ip string) (GRS, error) {
  99. // var data map[string]interface{}
  100. var data GRSRaw
  101. args := url.Values{}
  102. args.Set("query-string", ip)
  103. args.Add("source", "ripe-grs")
  104. args.Add("source", "arin-grs")
  105. args.Add("source", "apnic-grs")
  106. args.Add("source", "lacnic-grs")
  107. args.Add("source", "afrinic-grs")
  108. resp, err := napping.Get(GRS_URL, &args, &data, nil)
  109. if err != nil {
  110. return GRS{}, errors.New(fmt.Sprint("Failed to load data from ", resp.Url, ": ", err))
  111. }
  112. if resp.Status() != 200 {
  113. return GRS{}, errors.New(fmt.Sprint("Failed to load data from GRS server: ", resp.Status()))
  114. }
  115. if len(data.ErrorMessages.ErrorMessage) > 0 {
  116. return GRS{}, errors.New(fmt.Sprint("No GRS data for ", ip, ": ", data.ErrorMessages.ErrorMessage[0].Text))
  117. }
  118. grs := GRS{}
  119. var grs_inetnum *Object
  120. var grs_route *Object
  121. var inetnum string
  122. for i, e := range data.Objects.Objects {
  123. switch e.Type {
  124. case "inetnum":
  125. grs_inetnum = &data.Objects.Objects[i]
  126. case "inet6num":
  127. grs_inetnum = &data.Objects.Objects[i]
  128. case "route":
  129. grs_route = &data.Objects.Objects[i]
  130. }
  131. }
  132. // Inetnum fields
  133. //
  134. if grs_inetnum != nil {
  135. for _, e := range grs_inetnum.Attributes.Attributes {
  136. switch e.Name {
  137. case "inetnum":
  138. inetnum = e.Value
  139. case "inet6num":
  140. inetnum = e.Value
  141. case "netname":
  142. grs.Name = e.Value
  143. case "descr":
  144. grs.Description = e.Value
  145. case "country":
  146. grs.Country = e.Value
  147. case "status":
  148. grs.Status = e.Value
  149. case "org":
  150. grs.Org = e.Value
  151. }
  152. }
  153. }
  154. // Route fields
  155. //
  156. if grs_route != nil {
  157. for _, e := range grs_route.Attributes.Attributes {
  158. switch e.Name {
  159. case "route":
  160. grs.Cidr = e.Value
  161. case "descr":
  162. grs.Description = e.Value
  163. }
  164. }
  165. }
  166. var ip_from net.IP
  167. var ip_to net.IP
  168. if inetnum != "" {
  169. _, network, err := net.ParseCIDR(inetnum)
  170. if err == nil {
  171. ip_from, ip_to = networkRange(network)
  172. grs.IpFrom = ip_from.String()
  173. grs.IpTo = ip_to.String()
  174. if grs.Cidr == "" {
  175. grs.Cidr = network.String()
  176. }
  177. } else {
  178. reg := regexp.MustCompile(`^\s*(\d+\.\d+\.\d+\.\d+)\s*-\s*(\d+\.\d+\.\d+\.\d+)\s*$`)
  179. matches := reg.FindAllStringSubmatch(inetnum, -1)
  180. if matches != nil && matches[0] != nil && matches[0][1] != "" && matches[0][2] != "" {
  181. grs.IpFrom = matches[0][1]
  182. grs.IpTo = matches[0][2]
  183. ip_from = net.ParseIP(grs.IpFrom)
  184. ip_to = net.ParseIP(grs.IpTo)
  185. }
  186. }
  187. grs.IpFromRaw = ip_from.To16()
  188. grs.IpToRaw = ip_to.To16()
  189. }
  190. return grs, nil
  191. }
  192. // Calculates the first and last IP addresses in an IPNet
  193. func networkRange(network *net.IPNet) (net.IP, net.IP) {
  194. netIP := network.IP.To16()
  195. firstIP := netIP.Mask(network.Mask)
  196. lastIP := net.ParseIP("::").To16()
  197. for i := 0; i < len(lastIP); i++ {
  198. lastIP[i] = netIP[i] | ^network.Mask[i]
  199. }
  200. return firstIP, lastIP
  201. }