-
Notifications
You must be signed in to change notification settings - Fork 43
/
range.go
113 lines (95 loc) · 2.35 KB
/
range.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package hostsparser
import (
"context"
"github.com/pkg/errors"
"github.com/yaklang/yaklang/common/utils"
"net"
"strconv"
"strings"
)
type ipRangeBlock struct {
ctx context.Context
hostsBlock
origin string
size int
containerHandler func(ip net.IP) bool
chanHandlerGetter func() chan string
}
func newIPRangeBlock(ctx context.Context, raw string) (*ipRangeBlock, error) {
if !strings.Contains(raw, "-") {
return nil, utils.Errorf("ip range should contains '-'")
}
rets := strings.Split(raw, "-")
if len(rets) != 2 {
return nil, errors.Errorf("range is invalid: %s", raw)
}
first, second := rets[0], rets[1]
ip1 := net.ParseIP(utils.FixForParseIP(first))
if ip1 == nil {
return nil, utils.Errorf("first ip block is error: %s", first)
}
createFromIPRange := func(i1, i2 net.IP) (*ipRangeBlock, error) {
end := utils.InetAtoN(i2)
start := utils.InetAtoN(i1)
if end > start {
return &ipRangeBlock{
ctx: ctx,
origin: raw,
size: int(end - start + 1),
containerHandler: func(ip net.IP) bool {
r := utils.InetAtoN(ip)
return r >= start && r <= end
},
chanHandlerGetter: func() chan string {
c := make(chan string)
go func() {
defer close(c)
GEN:
for i := start; true; i++ {
if i > end {
break
}
select {
case <-ctx.Done():
break GEN
default:
}
select {
case c <- utils.InetNtoA(i).String():
}
}
}()
return c
},
}, nil
} else {
return nil, errors.Errorf("second[%v - %v] block should be larger than first[%v - %v]", i2, end, i1, start)
}
}
ip2 := net.ParseIP(utils.FixForParseIP(second))
if ip2 != nil {
return createFromIPRange(ip1, ip2)
}
secondEnd, err := strconv.ParseInt(second, 10, 64)
if err != nil {
return nil, errors.Errorf("second block is not a int: %v", second)
}
if secondEnd >= 255 {
secondEnd = 255
}
var rawIp1 []byte = ip1.To4()
ip2 = net.IP{rawIp1[0], rawIp1[1], rawIp1[2], byte(secondEnd)}
return createFromIPRange(ip1, ip2)
}
func (p *ipRangeBlock) Size() int {
return p.size
}
func (p *ipRangeBlock) Contains(raw string) bool {
if i := net.ParseIP(utils.FixForParseIP(raw)); i != nil {
return p.containerHandler(i)
}
return p.origin == raw
}
func (p *ipRangeBlock) Hosts() chan string {
return p.chanHandlerGetter()
}