Just starting out? Need help? Post your questions and find answers here.
Armoured
Enthusiast
Posts: 365 Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:
Post
by Armoured » Fri Mar 08, 2024 9:07 pm
On the German section of the forum, I came across the following post:
https://www.purebasic.fr/german/viewtop ... 15#p258815
In this example, the network card's gateway is not being returned. How can one retrieve it? Additionally, I've noticed that the "IP_ADAPTER_GATEWAY_ADDRESS_LH" structure seems to be missing, which I believe is intended for this purpose.
Could you provide me with an example that includes it? I attempted to post in the German forum, but encountered difficulties in doing so.
Thanks.
HeX0R
Addict
Posts: 1219 Joined: Mon Sep 20, 2004 7:12 am
Location: Hell
Post
by HeX0R » Fri Mar 08, 2024 10:17 pm
That code is pretty old, and also not complete.
Since I have no more use for it, I'm not willing to update it for a complete usage of GetAdaptersAddresses(), but you can try forcing it to use the old way by:
Armoured
Enthusiast
Posts: 365 Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:
Post
by Armoured » Fri Mar 08, 2024 11:10 pm
Hi,
Unfortunately, the issue persists and it's still not possible to retrieve the gateway.
In my version, I've implemented these structures. Can you tell me if they seem valid to you?
Code: Select all
Structure IP_ADAPTER_ADDRESSES
Length.l ; unsigned
IfIndex.l
*Next.IP_ADAPTER_ADDRESSES
*AdapterName
*FirstUnicastAddress;.PIP_ADAPTER_UNICAST_ADDRESS
*FirstAnycastAddress;.PIP_ADAPTER_ANYCAST_ADDRESS
*FirstMulticastAddress;.PIP_ADAPTER_MULTICAST_ADDRESS
*FirstDnsServerAddress;.PIP_ADAPTER_DNS_SERVER_ADDRESS
*DnsSuffix ;.PWCHAR
*Description ;.PWCHAR
*FriendlyName ;.PWCHAR
PhysicalAddress.b [#MAX_ADAPTER_ADDRESS_LENGTH]
PhysicalAddressLength.l
Flags.l
Mtu.l
IfType.l
OperStatus.l
Ipv6IfIndex.l
ZoneIndices.l [16]
*FirstPrefix;.PIP_ADAPTER_PREFIX
;Le successive voci sono state aggiunte da me per ricavare il gateway
TransmitLinkSpeed.q
ReceiveLinkSpeed.q
*FirstWinsServerAddress;PIP_ADAPTER_WINS_SERVER_ADDRESS_LH
*FirstGatewayAddress;PIP_ADAPTER_GATEWAY_ADDRESS_LH
EndStructure
Structure SOCKET_ADDRESS
*lpSockaddr
iSockaddrLength.l
EndStructure
Structure IP_ADAPTER_GATEWAY_ADDRESS_LH
Length.l
Reserved.l
*Next.IP_ADAPTER_GATEWAY_ADDRESS_LH
Address.SOCKET_ADDRESS
EndStructure
Thanks.
HeX0R
Addict
Posts: 1219 Joined: Mon Sep 20, 2004 7:12 am
Location: Hell
Post
by HeX0R » Fri Mar 08, 2024 11:14 pm
Armoured wrote: Fri Mar 08, 2024 11:10 pm
Hi,
Unfortunately, the issue persists and it's still not possible to retrieve the gateway.
You might have to add #GAA_FLAG_INCLUDE_GATEWAYS to the *THIS\GetAdaptersAddresses() call (in IFNA_Refresh())
idle
Always Here
Posts: 6031 Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand
Post
by idle » Fri Mar 08, 2024 11:22 pm
Armoured
Enthusiast
Posts: 365 Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:
Post
by Armoured » Sat Mar 09, 2024 2:37 am
I tried to simplify as much as possible to be able to post an example here. What I would expect to get is a decimal version of the Gateway IP, but unfortunately, I only get a memory access error. What am I doing wrong? Do you have any suggestions to offer? Thank you.
Code: Select all
#IF_TYPE_ETHERNET_CSMACD = 6
#MAX_ADAPTER_ADDRESS_LENGTH = 8
#GAA_FLAG_INCLUDE_GATEWAYS = 128 ;$0080
#ERROR_ADDRESS_NOT_ASSOCIATED = 1228
Structure MIB_IPADDRROW
dwAddr.l
dwIndex.l
dwMask.l
dwBCastAddr.l
dwReasmSize.l
unused1.w
wType.w
EndStructure
Structure MIB_IPADDRTABLE
dwNumEntries.l
*ips.MIB_IPADDRROW
EndStructure
Structure SOCKET_ADDRESS
*lpSockaddr
iSockaddrLength.l
EndStructure
Structure IP_ADAPTER_PREFIX
; union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } ; } ;
Length.l
Flags.l
*Next.IP_ADAPTER_PREFIX
Address.SOCKET_ADDRESS
PrefixLength.l
EndStructure
Structure IP_ADAPTER_GATEWAY_ADDRESS_LH
; union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } ; } ;
Length.l
Reserved.l
*Next.IP_ADAPTER_GATEWAY_ADDRESS_LH
Address.SOCKET_ADDRESS
EndStructure
Structure IP_ADAPTER_ADDRESSES
Length.l ; unsigned
IfIndex.l
*Next.IP_ADAPTER_ADDRESSES
*AdapterName
*FirstUnicastAddress;.PIP_ADAPTER_UNICAST_ADDRESS
*FirstAnycastAddress;.PIP_ADAPTER_ANYCAST_ADDRESS
*FirstMulticastAddress;.PIP_ADAPTER_MULTICAST_ADDRESS
*FirstDnsServerAddress;.PIP_ADAPTER_DNS_SERVER_ADDRESS
*DnsSuffix ;.PWCHAR
*Description ;.PWCHAR
*FriendlyName ;.PWCHAR
PhysicalAddress.b [#MAX_ADAPTER_ADDRESS_LENGTH]
PhysicalAddressLength.l
Flags.l
Mtu.l
IfType.l
OperStatus.l
Ipv6IfIndex.l
ZoneIndices.l [16]
*FirstPrefix;.PIP_ADAPTER_PREFIX
TransmitLinkSpeed.q
ReceiveLinkSpeed.q
*FirstWinsServerAddress;PIP_ADAPTER_WINS_SERVER_ADDRESS_LH
*FirstGatewayAddress;PIP_ADAPTER_GATEWAY_ADDRESS_LH
EndStructure
Procedure ListIPs()
Protected dll = OpenLibrary(#PB_Any, "iphlpapi.dll")
Protected tablesize = SizeOf(IP_ADAPTER_ADDRESSES)
Protected *table.IP_ADAPTER_ADDRESSES = AllocateMemory(tablesize)
Protected *info.IP_ADAPTER_ADDRESSES
Protected valid = #False
;Variabili per la parte che scorre i vari IP associati alle schede di rete
Protected iptablesize = SizeOf(MIB_IPADDRTABLE)
Protected *iptable.MIB_IPADDRTABLE = AllocateMemory(iptablesize)
Protected *ipinfo.MIB_IPADDRROW
Protected interfaceindex
Protected ipvalid = #False
Protected loop.l
If (dll)
Define GetAdaptersAddresses = GetFunction(dll, "GetAdaptersAddresses")
If (GetAdaptersAddresses)
Repeat
Select CallFunctionFast(GetAdaptersAddresses, #AF_INET, #GAA_FLAG_INCLUDE_GATEWAYS, #Null, *table, @tablesize)
Case #NO_ERROR
; Can exit loop now...
valid = #True
Case #ERROR_ADDRESS_NOT_ASSOCIATED
If IsLibrary(dll)
CloseLibrary(dll)
EndIf
FreeMemory(*table)
ProcedureReturn
Case #ERROR_BUFFER_OVERFLOW
; Increase buffer size and try again...
*table = ReAllocateMemory(*table, tablesize)
Default
If IsLibrary(dll)
CloseLibrary(dll)
EndIf
FreeMemory(*table)
ProcedureReturn
EndSelect
Until valid
EndIf
EndIf
*info.IP_ADAPTER_ADDRESSES = *table
While *info
Select *info\ifType
;La scheda è Ethernet
Case #IF_TYPE_ETHERNET_CSMACD
;se l'interfaccia è in funzione e in grado di trasmettere e ricevere
If (*info\OperStatus = 1)
Repeat
Select GetIpAddrTable_(*iptable, @iptablesize, #True)
Case #NO_ERROR
ipvalid = #True
Case #ERROR_INSUFFICIENT_BUFFER
*iptable = ReAllocateMemory (*iptable, iptablesize)
EndSelect
Until ipvalid
*ipinfo.MIB_IPADDRROW = @*iptable\ips
For loop = 0 To *iptable\dwNumEntries - 1
interfaceindex = *ipinfo\dwIndex
If interfaceindex > 0
If (interfaceindex = *info\IfIndex)
Debug "Description: " + PeekS(*table\Description, -1, #PB_Unicode) + #CRLF$
Define *gatewaylist.IP_ADAPTER_GATEWAY_ADDRESS_LH = *info\FirstGatewayAddress
Define *gateway.SOCKET_ADDRESS = *gatewaylist\Address
Debug "Gateway: " + Str(PeekQ(*gateway\lpSockaddr)) ;I have a memory access error here
EndIf
EndIf
*ipinfo = *ipinfo + SizeOf (MIB_IPADDRROW)
Next loop
EndIf
EndSelect
*info = *info\Next
Wend
FreeMemory(*iptable)
FreeMemory(*table)
EndProcedure
ListIPs()
idle
Always Here
Posts: 6031 Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand
Post
by idle » Sat Mar 09, 2024 3:00 am
doesn't my code above print the gateway ?
Name {0CA112EB-9D58-4953-A09A-A3EFFC0CB6E9}
Description Intel(R) Wi-Fi 6 AX200 160MHz
DHCP 1
Address 192.168.1.2
Mask 255.255.255.0
Gateway 192.168.1.1
Index 3
mac address A4:EF:C8:BE:3C:2D
DHCP: LeaseObtained 09.03.2024 11:39:21
DHCP: LeaseExpires 10.03.2024 11:39:21
DNS servers list
127.0.0.1
1.1.1.1
Armoured
Enthusiast
Posts: 365 Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:
Post
by Armoured » Sat Mar 09, 2024 3:13 am
idle wrote: Sat Mar 09, 2024 3:00 am
doesn't my code above print the gateway ?
Name {0CA112EB-9D58-4953-A09A-A3EFFC0CB6E9}
Description Intel(R) Wi-Fi 6 AX200 160MHz
DHCP 1
Address 192.168.1.2
Mask 255.255.255.0
Gateway 192.168.1.1
Index 3
mac address A4:EF:C8:BE:3C:2D
DHCP: LeaseObtained 09.03.2024 11:39:21
DHCP: LeaseExpires 10.03.2024 11:39:21
DNS servers list
127.0.0.1
1.1.1.1
Yes, yours correctly displays the gateway, but it doesn't use GetAdaptersAddresses, and this would force me to rewrite a large part of my code.
idle
Always Here
Posts: 6031 Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand
Post
by idle » Sat Mar 09, 2024 5:12 am
I'm a bit fatigued, it's almost there
Code: Select all
EnumerationBinary IP_ADAPTER_ADDRESSES_Flags
#DdnsEnabled=1
#RegisterAdapterSuffix
#Dhcpv4Enabled
#ReceiveOnly
#NoMulticast
#Ipv6OtherStatefulConfig
#NetbiosOverTcpipEnabled
#Ipv4Enabled
#Ipv6Enabled
#Ipv6ManagedAddressConfigurationSupported
EndEnumeration
#IF_TYPE_ETHERNET_CSMACD = 6
#MAX_ADAPTER_ADDRESS_LENGTH=8
#MAX_DHCPV6_DUID_LENGTH=16
#ERROR_ADDRESS_NOT_ASSOCIATED = 1228
#GAA_FLAG_INCLUDE_GATEWAYS = $80
Structure MIB_IPADDRROW
dwAddr.l
dwIndex.l
dwMask.l
dwBCastAddr.l
dwReasmSize.l
unused1.w
wType.w
EndStructure
Structure MIB_IPADDRTABLE
dwNumEntries.l
*ips.MIB_IPADDRROW
EndStructure
Structure SOCKET_ADDRESS
*lpSockaddr;
iSockaddrLength.l;
EndStructure
Structure IP_ADAPTER_ADDRESSES_LH
StructureUnion
Length.q;
IfIndex.l;
EndStructureUnion;
*next.IP_ADAPTER_ADDRESSES_LH
*AdapterName;
*FirstUnicastAddress;.PIP_ADAPTER_UNICAST_ADDRESS_LH ;
*FirstAnycastAddress;.PIP_ADAPTER_ANYCAST_ADDRESS_XP;
*FirstMulticastAddress;.PIP_ADAPTER_MULTICAST_ADDRESS_XP;
*FirstDnsServerAddress;.PIP_ADAPTER_DNS_SERVER_ADDRESS_XP;
DnsSuffix.s;
Description.s;
FriendlyName.s;
PhysicalAddress.a[#MAX_ADAPTER_ADDRESS_LENGTH];
PhysicalAddressLength.l;
Flags.l; enum IP_ADAPTER_ADDRESSES_Flags bitfield
Mtu.l;
IfType.l;IFTYPE
OperStatus.l;IF_OPER_STATUS ;
Ipv6IfIndex.l;IF_INDEX ;
ZoneIndices.l[16];
*FirstPrefix;.PIP_ADAPTER_PREFIX_XP;
TransmitLinkSpeed.q;
ReceiveLinkSpeed.q;
*FirstWinsServerAddress;.PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;
*FirstGatewayAddress;.PIP_ADAPTER_GATEWAY_ADDRESS_LH;
Ipv4Metric.l;
Ipv6Metric.l;
Luid.l;IF_LUID;
Dhcpv4Server.SOCKET_ADDRESS;
CompartmentId.l;NET_IF_COMPARTMENT_ID;
NetworkGuid.l;NET_IF_NETWORK_GUID;
ConnectionType.l;NET_IF_CONNECTION_TYPE ;
TunnelType.l;TUNNEL_TYPE;
Dhcpv6Server.SOCKET_ADDRESS ;
Dhcpv6ClientDuid.a[#MAX_DHCPV6_DUID_LENGTH];
Dhcpv6ClientDuidLength.l;
Dhcpv6Iaid.l;
*FirstDnsSuffix;.PIP_ADAPTER_DNS_SUFFIX ;
EndStructure
Structure IP_ADAPTER_GATEWAY_ADDRESS_LH
; union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } ; } ;
StructureUnion
Length.q
Reserved.l
EndStructureUnion
*Next.IP_ADAPTER_GATEWAY_ADDRESS_LH
Address.SOCKET_ADDRESS
EndStructure
ImportC "iphlpapi.lib"
GetAdaptersAddresses(Family.l,Flags.l,*Reserved,*AdapterAddresses,*SizePointer)
EndImport
Procedure ListIPs()
Protected *table.IP_ADAPTER_ADDRESSES_LH = AllocateMemory(SizeOf(IP_ADAPTER_ADDRESSES_LH))
Protected tablesize = SizeOf(IP_ADAPTER_ADDRESSES_LH)
Protected iptablesize = SizeOf(MIB_IPADDRTABLE)
Protected *iptable.MIB_IPADDRTABLE = AllocateMemory(iptablesize)
Protected *ipinfo.MIB_IPADDRROW
Repeat
Select GetAdaptersAddresses(#AF_INET, #GAA_FLAG_INCLUDE_GATEWAYS, #Null, *table, @tablesize)
Case #NO_ERROR
; Can exit loop now...
valid = #True
Case #ERROR_ADDRESS_NOT_ASSOCIATED
FreeMemory(*table)
ProcedureReturn
Case #ERROR_BUFFER_OVERFLOW
; Increase buffer size and try again...
*table = ReAllocateMemory(*table, tablesize)
Default
FreeMemory(*table)
ProcedureReturn
EndSelect
Until valid
If *table
*info.IP_ADAPTER_ADDRESSES_LH = *table
While *info
Select *info\ifType
;La scheda è Ethernet
Case #IF_TYPE_ETHERNET_CSMACD,71
;se l'interfaccia è in funzione e in grado di trasmettere e ricevere
If (*info\OperStatus = 1)
Repeat
Select GetIpAddrTable_(*iptable, @iptablesize, #True)
Case #NO_ERROR
ipvalid = #True
Case #ERROR_INSUFFICIENT_BUFFER
*iptable = ReAllocateMemory (*iptable, iptablesize)
EndSelect
Until ipvalid
*ipinfo.MIB_IPADDRROW = @*iptable\ips
For loop = 0 To *iptable\dwNumEntries - 1
interfaceindex = *ipinfo\dwIndex
If interfaceindex > 0
;If (interfaceindex = *info\IfIndex)
Debug "Description: " + *info\Description + #CRLF$
Define *gatewaylist.IP_ADAPTER_GATEWAY_ADDRESS_LH = *info\FirstGatewayAddress
Define *gateway.SOCKET_ADDRESS = *gatewaylist\Address
Debug "Gateway: " + Str(*gateway\lpSockaddr) ;I have a memory access error here
;EndIf
EndIf
*ipinfo = *ipinfo + SizeOf (MIB_IPADDRROW)
Next loop
EndIf
EndSelect
*info = *info\Next
Wend
FreeMemory(*iptable)
FreeMemory(*table)
EndIf
EndProcedure
ListIPs()
breeze4me
Enthusiast
Posts: 633 Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor
Post
by breeze4me » Sat Mar 09, 2024 11:09 am
Try this.
Code: Select all
#IF_TYPE_ETHERNET_CSMACD = 6
#IF_TYPE_IEEE80211 = 71
#MAX_ADAPTER_ADDRESS_LENGTH = 8
#GAA_FLAG_INCLUDE_GATEWAYS = 128 ;$0080
#ERROR_ADDRESS_NOT_ASSOCIATED = 1228
Structure MIB_IPADDRROW
dwAddr.l
dwIndex.l
dwMask.l
dwBCastAddr.l
dwReasmSize.l
unused1.w
wType.w
EndStructure
Structure MIB_IPADDRTABLE
dwNumEntries.l
*ips.MIB_IPADDRROW
EndStructure
Structure SOCKET_ADDRESS
*lpSockaddr.SOCKADDR_IN
iSockaddrLength.l
EndStructure
Structure IP_ADAPTER_PREFIX
; union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } ; } ;
Length.l
Flags.l
*Next.IP_ADAPTER_PREFIX
Address.SOCKET_ADDRESS
PrefixLength.l
EndStructure
Structure IP_ADAPTER_GATEWAY_ADDRESS_LH
; union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } ; } ;
Length.l
Reserved.l
*Next.IP_ADAPTER_GATEWAY_ADDRESS_LH
Address.SOCKET_ADDRESS
EndStructure
Structure IP_ADAPTER_ADDRESSES
Length.l ; unsigned
IfIndex.l
*Next.IP_ADAPTER_ADDRESSES
*AdapterName
*FirstUnicastAddress;.PIP_ADAPTER_UNICAST_ADDRESS
*FirstAnycastAddress;.PIP_ADAPTER_ANYCAST_ADDRESS
*FirstMulticastAddress;.PIP_ADAPTER_MULTICAST_ADDRESS
*FirstDnsServerAddress;.PIP_ADAPTER_DNS_SERVER_ADDRESS
*DnsSuffix ;.PWCHAR
*Description ;.PWCHAR
*FriendlyName ;.PWCHAR
PhysicalAddress.b [#MAX_ADAPTER_ADDRESS_LENGTH]
PhysicalAddressLength.l
Flags.l
Mtu.l
IfType.l
OperStatus.l
Ipv6IfIndex.l
ZoneIndices.l [16]
*FirstPrefix;.PIP_ADAPTER_PREFIX
TransmitLinkSpeed.q
ReceiveLinkSpeed.q
*FirstWinsServerAddress;PIP_ADAPTER_WINS_SERVER_ADDRESS_LH
*FirstGatewayAddress;PIP_ADAPTER_GATEWAY_ADDRESS_LH
EndStructure
Procedure ListIPs()
Protected dll = OpenLibrary(#PB_Any, "iphlpapi.dll")
Protected GetAdaptersAddresses
Protected tablesize
Protected *table.IP_ADAPTER_ADDRESSES
Protected *info.IP_ADAPTER_ADDRESSES
;Variabili per la parte che scorre i vari IP associati alle schede di rete
Protected iptablesize
Protected *iptable.MIB_IPADDRTABLE
Protected *ipinfo.MIB_IPADDRROW
Protected interfaceindex
Protected loop.l
Protected *gatewaylist.IP_ADAPTER_GATEWAY_ADDRESS_LH
Protected *str
Protected Result
If (dll)
GetAdaptersAddresses = GetFunction(dll, "GetAdaptersAddresses")
If (GetAdaptersAddresses)
If CallFunctionFast(GetAdaptersAddresses, #AF_INET, #GAA_FLAG_INCLUDE_GATEWAYS, #Null, 0, @tablesize) = #ERROR_BUFFER_OVERFLOW
If tablesize > 0
*table = AllocateMemory(tablesize)
If *table
If CallFunctionFast(GetAdaptersAddresses, #AF_INET, #GAA_FLAG_INCLUDE_GATEWAYS, #Null, *table, @tablesize) = #NO_ERROR
Result = 1
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
If Result = 0 : Goto Proc_Exit : EndIf
Result = 0
If GetIpAddrTable_(0, @iptablesize, #True) = #ERROR_INSUFFICIENT_BUFFER
If iptablesize > 0
*iptable = AllocateMemory(iptablesize)
If *iptable
If GetIpAddrTable_(*iptable, @iptablesize, #True) = #NO_ERROR
Result = 1
EndIf
EndIf
EndIf
EndIf
If Result = 0 : Goto Proc_Exit : EndIf
*info = *table
While *info
Select *info\ifType
Case #IF_TYPE_ETHERNET_CSMACD, #IF_TYPE_IEEE80211
;se l'interfaccia è in funzione e in grado di trasmettere e ricevere
If (*info\OperStatus = 1)
*ipinfo = @*iptable\ips
If *ipinfo = 0 : Break : EndIf
For loop = 0 To *iptable\dwNumEntries - 1
interfaceindex = *ipinfo\dwIndex
If interfaceindex > 0
If (interfaceindex = *info\IfIndex)
If *info\FirstGatewayAddress = 0 : Continue : EndIf
If *info\Description
Debug "Description: " + PeekS(*info\Description, -1, #PB_Unicode)
EndIf
*gatewaylist = *info\FirstGatewayAddress
If *gatewaylist And *gatewaylist\Address\lpSockaddr\sin_addr
*str = inet_ntoa_(*gatewaylist\Address\lpSockaddr\sin_addr)
If *str
Debug "Gateway: " + PeekS(*str, -1, #PB_Ascii)
EndIf
EndIf
EndIf
EndIf
*ipinfo = *ipinfo + SizeOf (MIB_IPADDRROW)
Next loop
EndIf
EndSelect
*info = *info\Next
Wend
Proc_Exit:
If *iptable : FreeMemory(*iptable) : EndIf
If *table : FreeMemory(*table) : EndIf
If dll : CloseLibrary(dll) : EndIf
EndProcedure
ListIPs()
Armoured
Enthusiast
Posts: 365 Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:
Post
by Armoured » Sat Mar 09, 2024 7:53 pm
Thank you breeze4me, your code has been very helpful! I also wanted to thank idle and HeX0R for their contributions.