-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathincr.go
81 lines (71 loc) · 1.38 KB
/
incr.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
package ipx
import (
"encoding/binary"
"errors"
"net"
)
// IncrIP returns the next IP
func IncrIP(ip net.IP, incr int) {
if ip == nil {
panic(errors.New("IP cannot be nil"))
}
if ip.To4() != nil {
n := to32(ip)
if incr >= 0 {
n += uint32(incr)
} else {
n -= uint32(incr * -1)
}
from32(n, ip)
return
}
// ipv6
u := To128(ip)
if incr >= 0 {
u = u.Add(Uint128{0, uint64(incr)})
} else {
u = u.Minus(Uint128{0, uint64(incr * -1)})
}
From128(u, ip)
}
// IncrNet steps to the next net of the same mask
func IncrNet(ipNet *net.IPNet, incr int) {
if ipNet.IP == nil {
panic(errors.New("IP cannot be nil"))
}
if ipNet.Mask == nil {
panic(errors.New("mask cannot be nil"))
}
if ipNet.IP.To4() != nil {
n := to32(ipNet.IP)
ones, bits := ipNet.Mask.Size()
suffix := uint32(bits - ones)
n >>= suffix
if incr >= 0 {
n += uint32(incr)
} else {
n -= uint32(incr * -1)
}
from32(n<<suffix, ipNet.IP)
return
}
b := To128(ipNet.IP)
ones, bits := ipNet.Mask.Size()
suffix := uint(bits - ones)
b = b.Rsh(suffix)
if incr >= 0 {
b = b.Add(Uint128{0, uint64(incr)})
} else {
b = b.Minus(Uint128{0, uint64(incr * -1)})
}
b = b.Lsh(suffix)
From128(b, ipNet.IP)
}
func to32(ip []byte) uint32 {
l := len(ip)
return binary.BigEndian.Uint32(ip[l-4:])
}
func from32(n uint32, ip []byte) {
l := len(ip)
binary.BigEndian.PutUint32(ip[l-4:], n)
}