在golang中将网络掩码号转换为32位

Converting netmask number to 32 bit in golang

我正在尝试通过

获取 IP 地址和子网掩码
ifaces, err := net.Interfaces()
for _, iface := range ifaces{
        localip, _ = iface.Addrs()
}

但是,我期待获得类似于 255.255.255.0 而不是 /24 的子网。我怎样才能得到它?如果没有模块可以做到这一点,作为一个程序这样做的逻辑是什么?

借自一些 Whosebug post 本身,使用逻辑运算符。

mask = (0xFFFFFFFF << (32 - 24)) & 0xFFFFFFFF; //24 is the netmask
var dmask uint64
dmask = 32
localmask := make([]uint64, 0, 4)
for i := 1; i <= 4; i++{
    tmp := mask >> (dmask - 8) & 0xFF
    localmask = append(localmask, tmp)
    dmask -= 8
}

fmt.Println(localmask)
func main() {
    ifaces, err := net.Interfaces()
    if err != nil {
        panic(err)
    }
    for _, iface := range ifaces {
        addrs, _ := iface.Addrs()
        for _, addr := range addrs {
            cidr := addr.String()
            mask, err := mask(cidr)
            if err != nil {
                fmt.Println("extracting mask failed:", err)
            }
            i, err := mtoi(mask)
            if err != nil {
                fmt.Println("creating uint16 from mask failed:", err)
            }
            fmt.Printf("CIDR: %s\tMask: %d\n", cidr, i)
        }
    }
}

// Extracts IP mask from CIDR address.
func mask(cidr string) (net.IPMask, error) {
    _, ip, err := net.ParseCIDR(cidr)
    return ip.Mask, err
}

// Converts IP mask to 16 bit unsigned integer.
func mtoi(mask net.IPMask) (uint16, error) {
    var i uint16
    buf := bytes.NewReader(mask)
    err := binary.Read(buf, binary.BigEndian, &i)
    return i, err
}

您可以实现如下功能:

func parseMask(ipaddr string) (mask string, err error) {
    removeExtra := regexp.MustCompile("^(.*[\/])")
    asd := ipaddr[len(ipaddr)-3:]
    findSubnet := removeExtra.ReplaceAll([]byte(asd), []byte(""))
    subnet, err := strconv.ParseInt(string(findSubnet), 10, 64)
    if err != nil {
        return "", errors.New("Parse Mask: Error parsing mask")
    }
    var buff bytes.Buffer
    for i := 0; i < int(subnet); i++ {
        buff.WriteString("1")
    }
    for i := subnet; i < 32; i++ {
        buff.WriteString("0")
    }
    masker := buff.String()
    a, _ := strconv.ParseUint(masker[:8], 2, 64)
    b, _ := strconv.ParseUint(masker[8:16], 2, 64)
    c, _ := strconv.ParseUint(masker[16:24], 2, 64)
    d, _ := strconv.ParseUint(masker[24:32], 2, 64)
    resultMask := fmt.Sprintf("%v.%v.%v.%v", a, b, c, d)
    return resultMask, nil
}

然后调用它:

func main() {
    ifaces, _ := net.Interfaces()
    for _, iface := range ifaces {
        localip, _ := iface.Addrs()
        for _, ip := range localip {
            done, _ := parseMask(ip.String())
            log.Println(done) // 255.255.255.0
        }
    }
}

在打印之前将网络掩码转换为类型 "IP" 就可以了:

func mask_print(ipnet *net.IPNet){
  fmt.Println("%v", net.IP(ipnet.Mask))      
}

我编写的以下函数适用于 ipv4:

func NetMaskToString(mask int) (netmaskstring string) {
var binarystring string

for ii := 1; ii <= mask; ii++ {
    binarystring = binarystring + "1"
}
for ii := 1; ii <= (32 - mask); ii++ {
    binarystring = binarystring + "0"
}
oct1 := binarystring[0:8]
oct2 := binarystring[8:16]
oct3 := binarystring[16:24]
oct4 := binarystring[24:]

ii1, _ := strconv.ParseInt(oct1, 2, 64)
ii2, _ := strconv.ParseInt(oct2, 2, 64)
ii3, _ := strconv.ParseInt(oct3, 2, 64)
ii4, _ := strconv.ParseInt(oct4, 2, 64)
netmaskstring = strconv.Itoa(int(ii1)) + "." + strconv.Itoa(int(ii2)) + "." + strconv.Itoa(int(ii3)) + "." + strconv.Itoa(int(ii4))
return

}