duanlu5055
duanlu5055
2016-01-08 08:42

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

  • ip
  • netmask
已采纳

I am trying to get the IP address and subnet mask by

ifaces, err := net.Interfaces()
for _, iface := range ifaces{
        localip, _ = iface.Addrs()
}

However, I am looking forward to get the subnet as something like 255.255.255.0 rather than /24. How can I get that? If there are no modules that can do this, what is the logic to do this as a program?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

4条回答

  • douxian6694 douxian6694 5年前

    Borrowed from some stackoverflow post itself, using logical operators.

    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)
    
    点赞 评论 复制链接分享
  • douzhi8244 douzhi8244 5年前

    You could implement a function like:

    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
    }
    

    and then call it:

    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
            }
        }
    }
    
    点赞 评论 复制链接分享
  • dongman2721 dongman2721 5年前
    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
    ", 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
    }
    
    点赞 评论 复制链接分享
  • douzhanhui5662 douzhanhui5662 4年前

    Converting netmask to type "IP" before printing does the trick:

    func mask_print(ipnet *net.IPNet){
      fmt.Println("%v", net.IP(ipnet.Mask))      
    }
    
    点赞 评论 复制链接分享

为你推荐