asn.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package asndb
  2. import (
  3. "bytes"
  4. "fmt"
  5. "net"
  6. "strconv"
  7. "github.com/google/btree"
  8. )
  9. // ASN contains information about a netblock
  10. type ASN struct {
  11. Network *net.IPNet `json:"network"`
  12. From *net.IP `json:"from"`
  13. To *net.IP `json:"to"`
  14. Cidr string `json:"cidr"`
  15. ASN int `json:"asn"`
  16. Organization string `json:"organization"`
  17. }
  18. // NewASN creates a new ASN struct based on cidr, asnr and org
  19. func NewASN(cidr string, asnr string, org string) (*ASN, error) {
  20. _, network, err := net.ParseCIDR(cidr)
  21. if err != nil {
  22. return nil, fmt.Errorf("cidr parse error for %s: %s", cidr, err)
  23. }
  24. asn, err := strconv.Atoi(asnr)
  25. if err != nil {
  26. return nil, fmt.Errorf("ASN parse error for %s: %s", asnr, err)
  27. }
  28. ip := network.IP.To16()
  29. mask := net.IPMask(make([]byte, net.IPv6len))
  30. if ip.To4() != nil {
  31. for i := 0; i < net.IPv6len-net.IPv4len; i++ {
  32. mask[i] = 0xff
  33. }
  34. for i, val := range network.Mask {
  35. mask[i+net.IPv6len-net.IPv4len] = val
  36. }
  37. } else {
  38. mask = network.Mask
  39. }
  40. firstIP := net.IP(make([]byte, 16))
  41. lastIP := net.IP(make([]byte, 16))
  42. for i := range ip {
  43. firstIP[i] = ip[i] & mask[i]
  44. lastIP[i] = ip[i] | ^mask[i]
  45. }
  46. return &ASN{
  47. Network: network,
  48. Organization: org,
  49. ASN: asn,
  50. From: &firstIP,
  51. To: &lastIP,
  52. Cidr: cidr,
  53. }, nil
  54. }
  55. // Less determines whether a is lexicographically smaller than bt
  56. func (a *ASN) Less(bt btree.Item) bool {
  57. b := bt.(*ASN)
  58. return bytes.Compare(*a.To, *b.To) < 0
  59. }