ing
This commit is contained in:
parent
01cc315e25
commit
7d0f0cdbd5
128
net/cidr/range-v4.go
Normal file
128
net/cidr/range-v4.go
Normal file
|
@ -0,0 +1,128 @@
|
|||
package cidr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"git.loafle.net/overflow/util-go/net/converter"
|
||||
)
|
||||
|
||||
type cidrRangeIPv4 struct {
|
||||
cidrNet *net.IPNet
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Contains(ip net.IP) bool {
|
||||
return cr.cidrNet.Contains(ip)
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) First() net.IP {
|
||||
nIP := cr.Network()
|
||||
return cr.Next(nIP)
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Last() net.IP {
|
||||
bIP := cr.Broadcast()
|
||||
return cr.Previous(bIP)
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Range() []net.IP {
|
||||
fIP := cr.First()
|
||||
if nil == fIP {
|
||||
return nil
|
||||
}
|
||||
lIP := cr.Last()
|
||||
if nil == lIP {
|
||||
return nil
|
||||
}
|
||||
fNum := converter.IPv4ToInt(fIP.To4())
|
||||
lNum := converter.IPv4ToInt(lIP.To4())
|
||||
|
||||
r := make([]net.IP, 0)
|
||||
for i := fNum; i <= lNum; i++ {
|
||||
r = append(r, converter.IntToIPv4(i))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// (!Contains(startIP) || !Contains(endIP)) return nil
|
||||
// (startIP > endIP) return nil
|
||||
// (nil != startIP && nil != endIP) return (startIP ~ endIP) + include - exclude
|
||||
// (nil == startIP || nil == endIP) return include - exclude
|
||||
func (cr *cidrRangeIPv4) Ranges(startIP net.IP, endIP net.IP, include []net.IP, exclude []net.IP) ([]net.IP, error) {
|
||||
|
||||
res := make(map[int32]bool)
|
||||
|
||||
if nil != startIP && nil != endIP {
|
||||
if !cr.Contains(startIP) {
|
||||
return nil, fmt.Errorf("CIDR Range: CIDR not contains start ip[%v]", startIP)
|
||||
}
|
||||
if !cr.Contains(endIP) {
|
||||
return nil, fmt.Errorf("CIDR Range: CIDR not contains end ip[%v]", endIP)
|
||||
}
|
||||
sNum := converter.IPv4ToInt(startIP.To4())
|
||||
eNum := converter.IPv4ToInt(endIP.To4())
|
||||
if sNum > eNum {
|
||||
return nil, fmt.Errorf("CIDR Range: Start IP[%v] must smaller then End IP[%v]", startIP, endIP)
|
||||
}
|
||||
for i := sNum; i <= eNum; i++ {
|
||||
res[i] = true
|
||||
}
|
||||
}
|
||||
|
||||
if nil != include {
|
||||
for _, in := range include {
|
||||
iNum := converter.IPv4ToInt(in.To4())
|
||||
if _, ok := res[iNum]; !ok {
|
||||
res[iNum] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if nil != exclude {
|
||||
for _, ex := range exclude {
|
||||
iNum := converter.IPv4ToInt(ex.To4())
|
||||
if _, ok := res[iNum]; ok {
|
||||
delete(res, iNum)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r := make([]net.IP, 0)
|
||||
for k, _ := range res {
|
||||
r = append(r, converter.IntToIPv4(k))
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Broadcast() net.IP {
|
||||
ip := cr.cidrNet.IP.To4()
|
||||
bIP := net.IPv4(0, 0, 0, 0).To4()
|
||||
for i := 0; i < len(bIP); i++ {
|
||||
bIP[i] = ip[i] | ^cr.cidrNet.Mask[i]
|
||||
}
|
||||
return bIP
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Network() net.IP {
|
||||
ip := cr.cidrNet.IP.To4()
|
||||
return ip.Mask(cr.cidrNet.Mask)
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Next(ip net.IP) net.IP {
|
||||
nNum := converter.IPv4ToInt(ip.To4()) + 1
|
||||
nIP := converter.IntToIPv4(nNum)
|
||||
if cr.Contains(nIP) {
|
||||
return nIP
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv4) Previous(ip net.IP) net.IP {
|
||||
nNum := converter.IPv4ToInt(ip.To4()) - 1
|
||||
nIP := converter.IntToIPv4(nNum)
|
||||
if cr.Contains(nIP) {
|
||||
return nIP
|
||||
}
|
||||
return nil
|
||||
}
|
43
net/cidr/range-v6.go
Normal file
43
net/cidr/range-v6.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package cidr
|
||||
|
||||
import "net"
|
||||
|
||||
type cidrRangeIPv6 struct {
|
||||
cidrNet *net.IPNet
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Contains(ip net.IP) bool {
|
||||
return cr.cidrNet.Contains(ip)
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) First() net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Last() net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Range() []net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Ranges(startIP net.IP, endIP net.IP, include []net.IP, exclude []net.IP) ([]net.IP, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Broadcast() net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Network() net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Next(ip net.IP) net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *cidrRangeIPv6) Previous(ip net.IP) net.IP {
|
||||
return nil
|
||||
}
|
44
net/cidr/range.go
Normal file
44
net/cidr/range.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package cidr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func NewCIDRRanger(cidr string) (CIDRRanger, error) {
|
||||
_, nIPNet, err := net.ParseCIDR(cidr)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch len(nIPNet.IP) {
|
||||
case net.IPv4len:
|
||||
cr := &cidrRangeIPv4{
|
||||
cidrNet: nIPNet,
|
||||
}
|
||||
return cr, nil
|
||||
case net.IPv6len:
|
||||
cr := &cidrRangeIPv6{
|
||||
cidrNet: nIPNet,
|
||||
}
|
||||
return cr, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Net: not supported IP length")
|
||||
}
|
||||
}
|
||||
|
||||
type CIDRRanger interface {
|
||||
Contains(ip net.IP) bool
|
||||
First() net.IP
|
||||
Last() net.IP
|
||||
Range() []net.IP
|
||||
// (!Contains(startIP) || !Contains(endIP)) return error
|
||||
// (startIP > endIP) return error
|
||||
// (nil != startIP && nil != endIP) return (startIP ~ endIP) + include - exclude
|
||||
// (nil == startIP || nil == endIP) return include - exclude
|
||||
Ranges(startIP net.IP, endIP net.IP, include []net.IP, exclude []net.IP) ([]net.IP, error)
|
||||
Broadcast() net.IP
|
||||
Network() net.IP
|
||||
Next(ip net.IP) net.IP
|
||||
Previous(ip net.IP) net.IP
|
||||
}
|
16
net/converter/ip-v4.go
Normal file
16
net/converter/ip-v4.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package converter
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
)
|
||||
|
||||
func IPv4ToInt(ip net.IP) int32 {
|
||||
return int32(binary.BigEndian.Uint32(ip.To4()))
|
||||
}
|
||||
|
||||
func IntToIPv4(n int32) net.IP {
|
||||
b := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(b, uint32(n))
|
||||
return net.IP(b)
|
||||
}
|
15
net/converter/ip-v6.go
Normal file
15
net/converter/ip-v6.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package converter
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// Not implemented
|
||||
func IPv6ToInt(ip net.IP) int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Not implemented
|
||||
func IntToIPv6(n int32) net.IP {
|
||||
return nil
|
||||
}
|
17
net/converter/ip.go
Normal file
17
net/converter/ip.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package converter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func IPToInt(ip net.IP) (int32, error) {
|
||||
switch len(ip) {
|
||||
case net.IPv4len:
|
||||
return IPv4ToInt(ip), nil
|
||||
case net.IPv6len:
|
||||
return IPv6ToInt(ip), nil
|
||||
default:
|
||||
return 0, fmt.Errorf("Net: not supported IP length")
|
||||
}
|
||||
}
|
18
net/converter/mac.go
Normal file
18
net/converter/mac.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package converter
|
||||
|
||||
import (
|
||||
"net"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
macStripRegexp = regexp.MustCompile(`[^a-fA-F0-9]`)
|
||||
)
|
||||
|
||||
func MacToUint64(hwAddr net.HardwareAddr) (uint64, error) {
|
||||
mac := hwAddr.String()
|
||||
hex := macStripRegexp.ReplaceAllLiteralString(mac, "")
|
||||
|
||||
return strconv.ParseUint(hex, 16, 64)
|
||||
}
|
Loading…
Reference in New Issue
Block a user