Created
January 25, 2015 03:07
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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