英文:
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 << (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)
答案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("^(.*[\\/])")
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
}
}
}
答案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 <= 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
}
答案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 (
"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)
// one way is to type assert
ipnet := localip.(*net.IPNet)
maskBytes := net.IP(ipnet.Mask)
fmt.Println("\tcasted mask is", maskBytes)
// another way is to parse the string
cidrStr := localip.String()
maskAddr := ipaddr.NewIPAddressString(cidrStr).GetAddress().
GetNetworkMask() // add .GetNetIP() for net.IP
fmt.Println("\tparsed mask is", 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论