-
-
Notifications
You must be signed in to change notification settings - Fork 10
Description
Hey there! I'm dealing with a problem trying to decode the data from a pointer argument passed to the GetIpInterfaceTable function. For context, this is the definition of the structures and function I have (which may be incorrect):
export const MIB_IPINTERFACE_ROW = koffi.struct('MIB_IPINTERFACE_ROW', {
Family: 'uint32',
InterfaceLuid: 'uint64',
InterfaceIndex: 'uint32',
MaxReassemblySize: 'uint32',
InterfaceIdentifier: 'uint64',
MinRouterAdvertisementInterval: 'uint32',
MaxRouterAdvertisementInterval: 'uint32',
AdvertisingEnabled: 'bool',
ForwardingEnabled: 'bool',
WeakHostSend: 'bool',
WeakHostReceive: 'bool',
UseAutomaticMetric: 'bool',
UseNeighborUnreachabilityDetection: 'bool',
ManagedAddressConfigurationSupported: 'bool',
OtherStatefulConfigurationSupported: 'bool',
AdvertisedReachableTime: 'uint32',
RouterDiscoveryBehavior: 'uint32',
DadTransmits: 'uint32',
BaseReachableTime: 'uint32',
RetransmitTimer: 'uint32',
PathMtuDiscoveryTimeout: 'uint32',
LinkLocalAddressBehavior: 'uint32',
LinkLocalAddressTimeout: 'uint32',
ZoneIndices: koffi.array('uint32', 16),
SitePrefixLength: 'uint8',
Metric: 'uint32',
NlMtu: 'uint32',
Connected: 'bool',
SupportWakeUpPatterns: 'bool',
SupportNeighborDiscovery: 'bool',
SupportRouterDiscovery: 'bool',
ReachableTime: 'uint32',
TransmitOffload: 'uint32',
ReceiveOffload: 'uint32',
DisableDefaultRoutes: 'bool',
});
...
iphlpapi.func(
'uint32 __stdcall GetIpInterfaceTable(uint16 Family, void **Table)',
)
And here is how I'm calling that function to get the pointer to the interfaces table:
const outPtrPtr = koffi.alloc('void *', 1);
const result = getIpInterfaceTableFunc(0, outPtrPtr);
if (result === WinError.NO_ERROR) {
const tablePtr = koffi.decode(outPtrPtr, 'void *');
const numEntries = koffi.decode(tablePtr, 'uint32');
const rowSize = koffi.sizeof(MIB_IPINTERFACE_ROW);
const numEntriesSize = koffi.sizeof('uint32');
...
I've tried different ways to decode the Table content, without success. Specifically, I've tried to:
- Create a dynamic structure for
MIB_IPINTERFACE_TABLEbased on thenumEntriesvalue decoded as auint32structure with the first bytes from the pointer.
const MIB_IPINTERFACE_TABLE = koffi.struct('MIB_IPINTERFACE_TABLE', {
NumEntries:'uint32,
Table: koffi.array(MIB_IPINTERFACE_ROW, numEntries),
});
const tableView = koffi.view(tablePtr, koffi.sizeof(MIB_IPINTERFACE_TABLE));
const table = koffi.decode(tableView, MIB_IPINTERFACE_TABLE);
- Creating chunks of byte arrays and decoding them calculating the offset for each row:
const totalSize = numEntriesSize + numEntries * rowSize;
const tableView = koffi.view(tablePtr, totalSize);
const rows = [];
for (let i = 0; i < numEntries; i++) {
const rowStart = numEntriesSize + i * rowSize;
const rowBuf = Buffer.from(tableView, rowStart, rowSize);
const row = koffi.decode(rowBuf, MIB_IPINTERFACE_ROW);
rows.push(row);
}
However, I get different errors on both implementations. Should I consider alignment/padding between rows? Could someone please tell me which is the right approach to access the table data on this or a similar scenario? Thanks!
Some extra context
If I create a placeholder structure for MIB_IPINTERFACE_TABLE as:
const MIB_IPINTERFACE_TABLE = koffi.struct('MIB_IPINTERFACE_TABLE', {
NumEntries:'uint32,
Table: koffi.array(MIB_IPINTERFACE_ROW, 1),
});
And I use it to decode the array buffer returned by the table pointer:
const tableView = koffi.view(tablePtr, totalSize);
const table = koffi.decode(tableView, MIB_IPINTERFACE_TABLE);
I can see that table contains an object with NumEntries and Table fields, but Table just contains the first MIB_IPINTERFACE_ROW entry, but I can't find a way to get the rest of rows without receiving errors from koffi.decode