2016-01-08 2 views
3

Я пытаюсь получить IP-адрес и маску подсетиПреобразование числа сетевой маски до 32 бит в golang

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

Однако, я с нетерпением жду, чтобы получить подсеть как нечто вроде 255.255.255.0, а не /24. Как я могу это получить? Если нет модулей, которые могут это сделать, какова логика для этого в качестве программы?

+1

Я думаю, что вы ищете https://golang.org/pkg/net/#IPMask.Size – kostya

ответ

2

Заимствован из какой-либо статьи stackoverflow, используя логические операторы.

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
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 
} 
+0

Не могли бы вы объяснить это как встроенный комментарий? – scott

+0

Я просто извлек две функции, чтобы сделать код чище. Обратите внимание, что 'net.Mask' определяется как' type IPMask [] byte', поэтому он может быть более полезен в этой форме. – kopiczko

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("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 
     } 
    } 
} 
2

Преобразование маску подсети для типа "IP" перед печатью делает трюк:

func mask_print(ipnet *net.IPNet){ 
    fmt.Println("%v", net.IP(ipnet.Mask))  
} 
Смежные вопросы