-
Notifications
You must be signed in to change notification settings - Fork 106
/
cidranger.go
99 lines (74 loc) · 2.65 KB
/
cidranger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
Package cidranger provides utility to store CIDR blocks and perform ip
inclusion tests against it.
To create a new instance of the path-compressed trie:
ranger := NewPCTrieRanger()
To insert or remove an entry (any object that satisfies the RangerEntry
interface):
_, network, _ := net.ParseCIDR("192.168.0.0/24")
ranger.Insert(NewBasicRangerEntry(*network))
ranger.Remove(network)
If you desire for any value to be attached to the entry, simply
create custom struct that satisfies the RangerEntry interface:
type RangerEntry interface {
Network() net.IPNet
}
To test whether an IP is contained in the constructed networks ranger:
// returns bool, error
containsBool, err := ranger.Contains(net.ParseIP("192.168.0.1"))
To get a list of CIDR blocks in constructed ranger that contains IP:
// returns []RangerEntry, error
entries, err := ranger.ContainingNetworks(net.ParseIP("192.168.0.1"))
To get a list of all IPv4/IPv6 rangers respectively:
// returns []RangerEntry, error
entries, err := ranger.CoveredNetworks(*AllIPv4)
entries, err := ranger.CoveredNetworks(*AllIPv6)
*/
package cidranger
import (
"fmt"
"net"
)
// ErrInvalidNetworkInput is returned upon invalid network input.
var ErrInvalidNetworkInput = fmt.Errorf("Invalid network input")
// ErrInvalidNetworkNumberInput is returned upon invalid network input.
var ErrInvalidNetworkNumberInput = fmt.Errorf("Invalid network number input")
// AllIPv4 is a IPv4 CIDR that contains all networks
var AllIPv4 = parseCIDRUnsafe("0.0.0.0/0")
// AllIPv6 is a IPv6 CIDR that contains all networks
var AllIPv6 = parseCIDRUnsafe("0::0/0")
func parseCIDRUnsafe(s string) *net.IPNet {
_, cidr, _ := net.ParseCIDR(s)
return cidr
}
// RangerEntry is an interface for insertable entry into a Ranger.
type RangerEntry interface {
Network() net.IPNet
}
type basicRangerEntry struct {
ipNet net.IPNet
}
func (b *basicRangerEntry) Network() net.IPNet {
return b.ipNet
}
// NewBasicRangerEntry returns a basic RangerEntry that only stores the network
// itself.
func NewBasicRangerEntry(ipNet net.IPNet) RangerEntry {
return &basicRangerEntry{
ipNet: ipNet,
}
}
// Ranger is an interface for cidr block containment lookups.
type Ranger interface {
Insert(entry RangerEntry) error
Remove(network net.IPNet) (RangerEntry, error)
Contains(ip net.IP) (bool, error)
ContainingNetworks(ip net.IP) ([]RangerEntry, error)
CoveredNetworks(network net.IPNet) ([]RangerEntry, error)
Len() int
}
// NewPCTrieRanger returns a versionedRanger that supports both IPv4 and IPv6
// using the path compressed trie implemention.
func NewPCTrieRanger() Ranger {
return newVersionedRanger(newPrefixTree)
}