func getIPForwardEntries()

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
}