in google_guest_agent/addresses_windows.go [329:379]
func getIPForwardEntries() ([]ipForwardEntry, error) {
buf := make([]byte, 1)
size := uint32(len(buf))
// First call gets the size of MIB_IPFORWARDTABLE.
procGetIpForwardTable.Call(
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&size)),
0,
)
buf = make([]byte, size)
if ret, _, _ := procGetIpForwardTable.Call(
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&size)),
0,
); ret != 0 {
return nil, fmt.Errorf("nonzero return code from GetIpForwardTable: %s", syscall.Errno(ret))
}
/*
struct MIB_IPFORWARDTABLE {
DWORD dwNumEntries;
MIB_IPFORWARDROW table[ANY_SIZE];
}
*/
numEntries := *(*uint32)(unsafe.Pointer(&buf[0]))
// Walk through the returned table for each entry.
var fes []ipForwardEntry
for i := uint32(0); i < numEntries; i++ {
// Extract each MIB_IPFORWARDROW from MIB_IPFORWARDTABLE
fr := *((*MIB_IPFORWARDROW)(unsafe.Pointer(
(uintptr(unsafe.Pointer(&buf[0])) + unsafe.Sizeof(numEntries)) + (unsafe.Sizeof(MIB_IPFORWARDROW{}) * uintptr(i)),
)))
fd := make([]byte, 4)
binary.LittleEndian.PutUint32(fd, uint32(fr.dwForwardDest))
fm := make([]byte, 4)
binary.LittleEndian.PutUint32(fm, uint32(fr.dwForwardMask))
nh := make([]byte, 4)
binary.LittleEndian.PutUint32(nh, uint32(fr.dwForwardNextHop))
fe := ipForwardEntry{
ipForwardDest: net.IP(fd),
ipForwardMask: net.IPMask(fm),
ipForwardNextHop: net.IP(nh),
ipForwardIfIndex: int32(fr.dwForwardIfIndex),
ipForwardMetric1: fr.dwForwardMetric1,
}
fes = append(fes, fe)
}
return fes, nil
}