// New Index object. func NewIndex() *Index { v6 := bitidx.NewNode(0) z := []byte(net.IPv4zero.To16()) v6.Put(bitidx.NewBits(z, 12*8+1), 0, false) v4, _, _ := v6.Find(bitidx.NewBits(z, 12*8)) return &Index{[]bitidx.Node{v6, v4}, map[string]int{"": 0}, []string{""}, 0} }
func TestParseRIR(t *testing.T) { a, x := ParseRIR("apnic|CN|ipv4|153.36.0.0|131072|20110331|allocated") b, y := ParseRIR("apnic|CN|ipv6|240c:8000::|21|20140905|allocated") t.Log(a, x) t.Log(b, y) n := bitidx.NewNode(0) n.Put(a.Bits(), 100, false) t.Log(n.Find(bitidx.NewBits([]byte((net.IP{153, 37, 0, 1}).To16()), -1))) t.Log(n.Find(bitidx.NewBits([]byte(net.IPv4zero.To16()), 12*8))) }
// RIR: Regional Internet Registry // https://ftp.apnic.net/stats/apnic/ // examples, // apnic|CN|ipv4|153.36.0.0|131072|20110331|allocated // apnic|CN|ipv6|240c:8000::|21|20140905|allocated // lacnic|VE|ipv4|190.168.0.0|32768|20070329|assigned // lacnic|VE|ipv4|190.168.128.0|16384|20070419|assigned func ParseRIR(line string) (r *Block, name string) { if ss := reRIR.FindStringSubmatch(line); len(ss) == 6 { if ip := net.ParseIP(ss[3]); ip != nil { mc, _ := strconv.ParseUint(ss[4], 10, 64) switch ss[2] { case "4": if count, ok := bit2loc[uint32(mc)]; ok { r = &Block{bitidx.NewBits([]byte(ip.To4()), count), BlockIPv4} name = ss[1] } case "6": r = &Block{bitidx.NewBits([]byte(ip), int(mc)), BlockIPv6} name = ss[1] } } } return }
// Restore structure from json previously exported. func NewIndexFromJson(rd io.Reader) (index *Index, extra interface{}) { var v *jsonIndex dec := json.NewDecoder(rd) if dec.Decode(&v) == nil { v.Index.ConsolidateNum() s, _, _ := v.Index.Find(bitidx.NewBits([]byte(net.IPv4zero.To16()), 12*8)) return &Index{[]bitidx.Node{v.Index, s}, v.Ids, v.Names, v.LastId}, v.Extra } return nil, nil }
func TestParseRIR1(t *testing.T) { a, x := ParseRIR("apnic|CN|ipv4|153.36.0.0|131072|20110331|allocated") b, y := ParseRIR("apnic|CN|ipv6|240c:8000::|21|20140905|allocated") t.Log(a, x) t.Log(b, y) r := bitidx.NewNode(0) r.Put(bitidx.NewBits([]byte(net.IPv4zero.To16()), 12*8+1), 0, false) s, _, _ := r.Find(bitidx.NewBits([]byte(net.IPv4zero.To16()), 12*8)) rs := []bitidx.Node{r, s} rs[a.Kind()].Put(a.Bits(), 10, false) rs[b.Kind()].Put(b.Bits(), 100, false) t.Log(r) t.Log(s) t.Log(rs[BlockIPv4].Find(bitidx.NewBits([]byte((net.IP{153, 37, 0, 1}).To4()), -1))) }
// Find ip for name. When no ip is found empty string is returned. func (index *Index) Find(ip string) (name string, length int) { if i := net.ParseIP(ip); i != nil { var n bitidx.Node if j := i.To4(); j != nil { n = index.index[BlockIPv4] i = j } else { n = index.index[BlockIPv6] } _, x, l := n.Find(bitidx.NewBits([]byte(i), -1)) if id, ok := x.(int); ok { name = index.names[id] length = l } } return }