This commit is contained in:
crusader 2017-11-17 19:07:00 +09:00
parent cbe7492057
commit 4bf418325b
6 changed files with 193 additions and 57 deletions

37
net/cidr/range.go Normal file
View File

@ -0,0 +1,37 @@
package cidr
import (
"fmt"
"net"
)
func NewCIDRRanger(cidr string) (CIDRRanger, error) {
nIP, nIPNet, err := net.ParseCIDR(cidr)
if nil != err {
return nil, err
}
switch len(nIP) {
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
Broadcast() net.IP
Network() net.IP
}

75
net/cidr/range_v4.go Normal file
View File

@ -0,0 +1,75 @@
package cidr
import (
"net"
"git.loafle.net/commons_go/util/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
}
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
}

39
net/cidr/range_v6.go Normal file
View File

@ -0,0 +1,39 @@
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 {
}
func (cr *cidrRangeIPv6) Last() net.IP {
}
func (cr *cidrRangeIPv6) Range() []net.IP {
}
func (cr *cidrRangeIPv6) Broadcast() net.IP {
}
func (cr *cidrRangeIPv6) Network() net.IP {
}
func (cr *cidrRangeIPv6) Next(ip net.IP) {
}
func (cr *cidrRangeIPv6) Previous(ip net.IP) {
}

View File

@ -1,64 +1,17 @@
package converter package converter
import ( import (
"strconv" "fmt"
"strings" "net"
) )
func IPToUint64(ip string) uint64 { func IPToInt(ip net.IP) (int32, error) {
isV4 := true switch len(ip) {
for i := 0; i < len(ip); i++ { case net.IPv4len:
switch ip[i] { return IPv4ToInt(ip), nil
case ':': case net.IPv6len:
isV4 = false return IPv6ToInt(ip), nil
break default:
case '.': return 0, fmt.Errorf("Net: not supported IP length")
isV4 = true
break
} }
} }
if !isV4 {
return ipv6ToUint64(ip)
}
return IPV4ToUint64(ip)
}
func IPV4ToUint64(s string) uint64 {
bits := strings.Split(s, ".")
b0, _ := strconv.Atoi(bits[0])
b1, _ := strconv.Atoi(bits[1])
b2, _ := strconv.Atoi(bits[2])
b3, _ := strconv.Atoi(bits[3])
var sum uint64
// left shifting 24,16,8,0 and bitwise OR
sum += uint64(b0) << 24
sum += uint64(b1) << 16
sum += uint64(b2) << 8
sum += uint64(b3)
return sum
}
func ipv6ToUint64(s string) uint64 {
bits := strings.Split(s, ":")
b0, _ := strconv.Atoi(bits[0])
b1, _ := strconv.Atoi(bits[1])
b2, _ := strconv.Atoi(bits[2])
b3, _ := strconv.Atoi(bits[3])
var sum uint64
// left shifting 24,16,8,0 and bitwise OR
sum += uint64(b0) << 24
sum += uint64(b1) << 16
sum += uint64(b2) << 8
sum += uint64(b3)
return sum
}

17
net/converter/ip_v4.go Normal file
View File

@ -0,0 +1,17 @@
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
View 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
}