Skip to content

Instantly share code, notes, and snippets.

@hnakamur
Created January 25, 2015 03:07
Show Gist options
  • Save hnakamur/15e5ee10dc42defc93dc to your computer and use it in GitHub Desktop.
Save hnakamur/15e5ee10dc42defc93dc to your computer and use it in GitHub Desktop.
List pairs of IPv4 address and netmask on Windows using Go (MIT License)
package main
import (
"fmt"
"net"
"os"
"syscall"
"unsafe"
)
// copied from https://github.com/golang/go/blob/go1.4.1/src/net/sock_windows.go#L15-L24
func sysSocket(f, t, p int) (syscall.Handle, error) {
// See ../syscall/exec_unix.go for description of ForkLock.
syscall.ForkLock.RLock()
s, err := syscall.Socket(f, t, p)
if err == nil {
syscall.CloseOnExec(s)
}
syscall.ForkLock.RUnlock()
return s, err
}
// copied from https://github.com/golang/go/blob/go1.4.1/src/net/interface_windows.go#L41-L57
func getInterfaceList() ([]syscall.InterfaceInfo, error) {
s, err := sysSocket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
if err != nil {
return nil, os.NewSyscallError("Socket", err)
}
defer syscall.Closesocket(s)
ii := [20]syscall.InterfaceInfo{}
ret := uint32(0)
size := uint32(unsafe.Sizeof(ii))
err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
if err != nil {
return nil, os.NewSyscallErmaskror("WSAIoctl", err)
}
c := ret / uint32(unsafe.Sizeof(ii[0]))
return ii[:c-1], nil
}
func IPNets() ([]net.IPNet, error) {
itfList, err := getInterfaceList()
if err != nil {
return nil, err
}
var ipnets []net.IPNet
for _, itf := range itfList {
// Copied from https://github.com/golang/go/blob/go1.4.1/src/net/interface_windows.go#L86-L87
ip := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&itf.Address)).Addr
ipv4 := net.IPv4(ip[0], ip[1], ip[2], ip[3])
ip = (*syscall.RawSockaddrInet4)(unsafe.Pointer(&itf.Netmask)).Addr
mask := net.IPv4Mask(ip[0], ip[1], ip[2], ip[3])
ipnets = append(ipnets, net.IPNet{IP: ipv4, Mask: mask})
}
return ipnets, nil
}
func main() {
ipnets, err := IPNets()
if err != nil {
panic(err)
}
for _, ipnet := range ipnets {
fmt.Printf("ipv4=%v, mask=%v\n", ipnet.IP, ipnet.Mask)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment