Converting netmask number to 32 bit in golang

huangapple go评论83阅读模式
英文:

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。我该如何实现这个功能?如果没有可以完成此任务的模块,有什么逻辑可以在程序中实现这个功能呢?

英文:

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?

答案1

得分: 4

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("提取掩码失败:", err)
            }
            i, err := mtoi(mask)
            if err != nil {
                fmt.Println("从掩码创建无符号16位整数失败:", err)
            }
            fmt.Printf("CIDR: %s\t掩码: %d\n", cidr, i)
        }
    }
}

// 从CIDR地址中提取IP掩码。
func mask(cidr string) (net.IPMask, error) {
    _, ip, err := net.ParseCIDR(cidr)
    return ip.Mask, err
}

// 将IP掩码转换为16位无符号整数。
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 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
}

答案2

得分: 3

将网络掩码转换为“IP”类型后再打印即可解决问题:

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

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

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

答案3

得分: 2

从某个stackoverflow帖子借鉴的代码,使用逻辑运算符。

mask = (0xFFFFFFFF << (32 - 24)) & 0xFFFFFFFF; //24是子网掩码
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)

英文:

Borrowed from some stackoverflow post itself, using logical operators.

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

fmt.Println(localmask)

答案4

得分: 1

你可以实现一个类似的函数:

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("解析掩码错误")
    }
    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
        }
    }
}
英文:

You could implement a function like:

func parseMask(ipaddr string) (mask string, err error) {
	removeExtra := regexp.MustCompile(&quot;^(.*[\\/])&quot;)
	asd := ipaddr[len(ipaddr)-3:]
	findSubnet := removeExtra.ReplaceAll([]byte(asd), []byte(&quot;&quot;))
	subnet, err := strconv.ParseInt(string(findSubnet), 10, 64)
	if err != nil {
		return &quot;&quot;, errors.New(&quot;Parse Mask: Error parsing mask&quot;)
	}
	var buff bytes.Buffer
	for i := 0; i &lt; int(subnet); i++ {
		buff.WriteString(&quot;1&quot;)
	}
	for i := subnet; i &lt; 32; i++ {
		buff.WriteString(&quot;0&quot;)
	}
    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(&quot;%v.%v.%v.%v&quot;, 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
		}
	}
}

答案5

得分: 0

以下是我翻译好的内容:

我编写的以下函数适用于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
}

这个函数将一个整数的网络掩码转换为字符串表示形式。

英文:

Following function that i wrote works for ipv4:

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

for ii := 1; ii &lt;= mask; ii++ {
	binarystring = binarystring + &quot;1&quot;
}
for ii := 1; ii &lt;= (32 - mask); ii++ {
	binarystring = binarystring + &quot;0&quot;
}
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)) + &quot;.&quot; + strconv.Itoa(int(ii2)) + &quot;.&quot; + strconv.Itoa(int(ii3)) + &quot;.&quot; + strconv.Itoa(int(ii4))
return

}

答案6

得分: 0

有几种选项。你可以使用类型断言来从net.IPNet中获取掩码,如下所示。或者你可以解析给定的CIDR地址。解析可以使用IPAddress Go库来完成,如下所示,或者使用net.ParseCIDR来获取net.IPNet并从中获取掩码。免责声明:我是IPAddress的项目经理。

package main

import (
	"fmt"
	"github.com/seancfoley/ipaddress-go/ipaddr"
	"net"
)

func main() {
	ifaces, _ := net.Interfaces()
	var localips []net.Addr
	for _, iface := range ifaces {
		addrs, _ := iface.Addrs()
		localips = append(localips, addrs...)
	}
	for _, localip := range localips {
		fmt.Println("for the IP", localip)

		// 一种方法是类型断言
		ipnet := localip.(*net.IPNet)
		maskBytes := net.IP(ipnet.Mask)
		fmt.Println("\tcasted mask is", maskBytes)

		// 另一种方法是解析字符串
		cidrStr := localip.String()
		maskAddr := ipaddr.NewIPAddressString(cidrStr).GetAddress().
			GetNetworkMask() // add .GetNetIP() for net.IP
		fmt.Println("\tparsed mask is", maskAddr)
	}
}

示例输出:

for the IP 127.0.0.1/8
        casted mask is 255.0.0.0
        parsed mask is 255.0.0.0
for the IP ::1/128
        casted mask is ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
        parsed mask is ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
for the IP fe80::1/64
        casted mask is ffff:ffff:ffff:ffff::
        parsed mask is ffff:ffff:ffff:ffff::
for the IP fe80::10ba:1591:f2b5:cfc7/64
        casted mask is ffff:ffff:ffff:ffff::
        parsed mask is ffff:ffff:ffff:ffff::
for the IP 192.168.1.165/24
        casted mask is 255.255.255.0
        parsed mask is 255.255.255.0
for the IP 9.211.112.150/19
        casted mask is 255.255.224.0
        parsed mask is 255.255.224.0
英文:

There are a couple of options. You can do a type assertion to *net.IPNet from which you can grab the mask, as shown. Or you can parse the given CIDR address. The parse can be done with the IPAddress Go library as shown, or by using net.ParseCIDR to get a *net.IPNet from which you can grab the mask. Disclaimer: I am the project manager for IPAddress.

package main

import (
	&quot;fmt&quot;
	&quot;github.com/seancfoley/ipaddress-go/ipaddr&quot;
	&quot;net&quot;
)

func main() {
	ifaces, _ := net.Interfaces()
	var localips []net.Addr
	for _, iface := range ifaces {
		addrs, _ := iface.Addrs()
		localips = append(localips, addrs...)
	}
	for _, localip := range localips {
		fmt.Println(&quot;for the IP&quot;, localip)

		// one way is to type assert
		ipnet := localip.(*net.IPNet)
		maskBytes := net.IP(ipnet.Mask)
		fmt.Println(&quot;\tcasted mask is&quot;, maskBytes)

		// another way is to parse the string
		cidrStr := localip.String()
		maskAddr := ipaddr.NewIPAddressString(cidrStr).GetAddress().
			GetNetworkMask() // add .GetNetIP() for net.IP
		fmt.Println(&quot;\tparsed mask is&quot;, maskAddr)
	}
}

Sample output:

for the IP 127.0.0.1/8
        casted mask is 255.0.0.0
        parsed mask is 255.0.0.0
for the IP ::1/128
        casted mask is ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
        parsed mask is ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
for the IP fe80::1/64
        casted mask is ffff:ffff:ffff:ffff::
        parsed mask is ffff:ffff:ffff:ffff::
for the IP fe80::10ba:1591:f2b5:cfc7/64
        casted mask is ffff:ffff:ffff:ffff::
        parsed mask is ffff:ffff:ffff:ffff::
for the IP 192.168.1.165/24
        casted mask is 255.255.255.0
        parsed mask is 255.255.255.0
for the IP 9.211.112.150/19
        casted mask is 255.255.224.0
        parsed mask is 255.255.224.0

huangapple
  • 本文由 发表于 2016年1月8日 16:42:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/34672725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定