123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- package cidr
- import (
- "bytes"
- "fmt"
- "math"
- "net"
- "sort"
- )
- // SuperNetting 合并网段
- func SuperNetting(ns []string) (*cidr, error) {
- num := len(ns)
- if num < 1 || (num&(num-1)) != 0 {
- return nil, fmt.Errorf("子网数量必须是2的次方")
- }
- mask := ""
- var cidrs []*cidr
- for _, n := range ns {
- // 检查子网CIDR有效性
- c, err := ParseCIDR(n)
- if err != nil {
- return nil, fmt.Errorf("网段%v格式错误", n)
- }
- cidrs = append(cidrs, c)
- // TODO 暂只考虑相同子网掩码的网段合并
- if len(mask) == 0 {
- mask = c.Mask()
- } else if c.Mask() != mask {
- return nil, fmt.Errorf("子网掩码不一致")
- }
- }
- AscSortCIDRs(cidrs)
- // 检查网段是否连续
- var network net.IP
- for _, c := range cidrs {
- if len(network) > 0 {
- if !network.Equal(c.ipNet.IP) {
- return nil, fmt.Errorf("必须是连续的网段")
- }
- }
- network = net.ParseIP(c.Broadcast())
- IncrIP(network)
- }
- // 子网掩码左移,得到共同的父网段
- c := cidrs[0]
- ones, bits := c.MaskSize()
- ones = ones - int(math.Log2(float64(num)))
- c.ipNet.Mask = net.CIDRMask(ones, bits)
- c.ipNet.IP.Mask(c.ipNet.Mask)
- return c, nil
- }
- // IncrIP IP地址自增
- func IncrIP(ip net.IP) {
- for i := len(ip) - 1; i >= 0; i-- {
- ip[i]++
- if ip[i] > 0 {
- break
- }
- }
- }
- // DecrIP IP地址自减
- func DecrIP(ip net.IP) {
- length := len(ip)
- for i := length - 1; i >= 0; i-- {
- ip[length-1]--
- if ip[length-1] < 0xFF {
- break
- }
- for j := 1; j < length; j++ {
- ip[length-j-1]--
- if ip[length-j-1] < 0xFF {
- return
- }
- }
- }
- }
- // Compare 比较IP大小 a等于b,返回0; a大于b,返回+1; a小于b,返回-1
- func Compare(a, b net.IP) int {
- return bytes.Compare(a, b)
- }
- // AscSortCIDRs 升序
- func AscSortCIDRs(cs []*cidr) {
- sort.Slice(cs, func(i, j int) bool {
- if n := bytes.Compare(cs[i].ipNet.IP, cs[j].ipNet.IP); n != 0 {
- return n < 0
- }
- if n := bytes.Compare(cs[i].ipNet.Mask, cs[j].ipNet.Mask); n != 0 {
- return n < 0
- }
- return false
- })
- }
- // DescSortCIDRs 降序
- func DescSortCIDRs(cs []*cidr) {
- sort.Slice(cs, func(i, j int) bool {
- if n := bytes.Compare(cs[i].ipNet.IP, cs[j].ipNet.IP); n != 0 {
- return n >= 0
- }
- if n := bytes.Compare(cs[i].ipNet.Mask, cs[j].ipNet.Mask); n != 0 {
- return n >= 0
- }
- return false
- })
- }
|