[Win]NetworkAdapterInterface
Verfasst: 19.10.2009 21:31
Moin,
es gibt ein paar Ansätze in den Boards die WinAPI GetAdaptersInfo() zu benutzen, um erweiterte Infos der integrierten Netzwerkadapter zu bekommen.
Aber irgendwie waren die alle etwas unpraktisch und auch nicht immer fehlerfrei.
Also habe ich mich daran gesetzt und das ganze als Interface umgesetzt.
Man kann quasi alle Informationen der API benutzen ausser das WINS-Zeugs, weil ich dafür keine Verwendung habe.
Ausserdem gibt es zwei interessante Zusatzfunktionen, wegen den ich das ganze überhaupt erst begonnen habe.
AddIPAddress() und DeleteIPAddress().
Der (Un)Sinn hinter dem ganzen war folgendes Szenario:
Wir haben im Geschäft ein paar Monteure, die mit PCs... nun nicht wirklich aufgewachsen sind.
Mittlerweile müssen aber die meisten unserer Anlagen über Netzwerkkabel bedient werden.
Nachdem ich eine geschlagene halbe Stunde erklärt hatte, wie man die IP seiner Netzwerkkarte in den Subnetzbereich der
jeweiligen Anlage umbiegen kann, dachte ich, das muss doch einfacher gehn...
Also hab ich jetzt ein kleines Programm gebastelt, mit dem man auf Knopfdruck die IP (temporär) anpassen kann.
O.k., genug gelabert, hier der Code:
und ein Beispiel:
1.10.22 => an PB6.0 angepasst
es gibt ein paar Ansätze in den Boards die WinAPI GetAdaptersInfo() zu benutzen, um erweiterte Infos der integrierten Netzwerkadapter zu bekommen.
Aber irgendwie waren die alle etwas unpraktisch und auch nicht immer fehlerfrei.
Also habe ich mich daran gesetzt und das ganze als Interface umgesetzt.
Man kann quasi alle Informationen der API benutzen ausser das WINS-Zeugs, weil ich dafür keine Verwendung habe.
Ausserdem gibt es zwei interessante Zusatzfunktionen, wegen den ich das ganze überhaupt erst begonnen habe.
AddIPAddress() und DeleteIPAddress().
Der (Un)Sinn hinter dem ganzen war folgendes Szenario:
Wir haben im Geschäft ein paar Monteure, die mit PCs... nun nicht wirklich aufgewachsen sind.
Mittlerweile müssen aber die meisten unserer Anlagen über Netzwerkkabel bedient werden.
Nachdem ich eine geschlagene halbe Stunde erklärt hatte, wie man die IP seiner Netzwerkkarte in den Subnetzbereich der
jeweiligen Anlage umbiegen kann, dachte ich, das muss doch einfacher gehn...
Also hab ich jetzt ein kleines Programm gebastelt, mit dem man auf Knopfdruck die IP (temporär) anpassen kann.
O.k., genug gelabert, hier der Code:
Code: Alles auswählen
;/--------------------------
;|
;| NetworkAdapterInterface_v02.pbi
;| V1.02 (22.10.2009)
;| ©HeX0R 2009
;|
;| for PB 4.x
;|
;| Add comments for yourself...
;/--------------------------
CompilerIf #PB_Compiler_Version < 600
InitNetwork()
CompilerEndIf
Prototype __GetAdaptersAddresses(Family.l, Flags.l, Reserved.l, *AdapterAddresses, *SizePointer)
#MAX_ADAPTER_NAME_LENGTH = 256
#MAX_ADAPTER_DESCRIPTION_LENGTH = 128
#MAX_ADAPTER_ADDRESS_LENGTH = 8
#MIB_IF_TYPE_OTHER = 1
#MIB_IF_TYPE_ETHERNET = 6
#MIB_IF_TYPE_TOKENRING = 9
#MIB_IF_TYPE_FDDI = 15
#MIB_IF_TYPE_PPP = 23
#MIB_IF_TYPE_LOOPBACK = 24
#MIB_IF_TYPE_SLIP = 28
#IF_TYPE_ATM = 37
#IF_TYPE_IEEE80211 = 71
#IF_TYPE_TUNNEL = 131
#IF_TYPE_IEEE1394 = 144
Enumeration
#MIB_IF_OPER_STATUS_NON_OPERATIONAL
#MIB_IF_OPER_STATUS_UNREACHABLE
#MIB_IF_OPER_STATUS_DISCONNECTED
#MIB_IF_OPER_STATUS_CONNECTING
#MIB_IF_OPER_STATUS_CONNECTED
#MIB_IF_OPER_STATUS_OPERATIONAL
EndEnumeration
Enumeration
#IpPrefixOriginOther
#IpPrefixOriginManual
#IpPrefixOriginWellKnown
#IpPrefixOriginDhcp
#IpPrefixOriginRouterAdvertisement
EndEnumeration
#IpPrefixOriginUnchanged = 16
#ScopeLevelInterface = 1
#ScopeLevelLink = 2
#ScopeLevelSubnet = 3
#ScopeLevelAdmin = 4
#ScopeLevelSite = 5
#ScopeLevelOrganization = 8
#ScopeLevelGlobal = 14
Enumeration
#IpSuffixOriginOther
#IpSuffixOriginManual
#IpSuffixOriginWellKnown
#IpSuffixOriginDhcp
#IpSuffixOriginLinkLayerAddress
#IpSuffixOriginRandom
EndEnumeration
#IpSuffixOriginUnchanged = 16
Enumeration
#IpDadStateInvalid
#IpDadStateTentative
#IpDadStateDuplicate
#IpDadStateDeprecated
#IpDadStatePreferred
EndEnumeration
Enumeration
#SELECT_UNICAST_ADDRESS
#SELECT_ANYCAST_ADDRESS
#SELECT_MULTICAST_ADDRESS
#SELECT_DNS_ADDRESS
EndEnumeration
#MIB_IF_ADMIN_STATUS_UP = 1
#MIB_IF_ADMIN_STATUS_DOWN = 2
#MIB_IF_ADMIN_STATUS_TESTING = 3
#IP_ADAPTER_DDNS_ENABLED = $0001 ;Dynamic DNS is enabled on this adapter.
#IP_ADAPTER_REGISTER_ADAPTER_SUFFIX = $0002 ;Register the DNS suffix For this adapter.
#IP_ADAPTER_DHCP_ENABLED = $0004 ;The Dynamic Host Configuration Protocol (DHCP) is enabled on this adapter.
#IP_ADAPTER_RECEIVE_ONLY = $0008 ;The adapter is a receive-only adapter.
#IP_ADAPTER_NO_MULTICAST = $0010 ;The adapter is not a multicast recipient.
#IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG = $0020 ;The adapter contains other IPv6-specific stateful configuration information.
#IP_ADAPTER_NETBIOS_OVER_TCPIP_ENABLED = $0040 ;The adapter is enabled For NetBIOS over TCP/IP.
#IP_ADAPTER_IPV4_ENABLED = $0080 ;The adapter is enabled For IPv4.
#IP_ADAPTER_IPV6_ENABLED = $0100 ;The adapter is enabled For IPv6.
#Ipv6ManagedAddressConfigurationSupported = $0200
#NI_NUMERICHOST = 1
#GAA_FLAG_SKIP_UNICAST = $0001
#GAA_FLAG_SKIP_ANYCAST = $0002
#GAA_FLAG_SKIP_MULTICAST = $0004
#GAA_FLAG_SKIP_DNS_SERVER = $0008
#GAA_FLAG_INCLUDE_PREFIX = $0010
#GAA_FLAG_SKIP_FRIENDLY_NAME = $0020
#GAA_FLAG_INCLUDE_ALL_INTERFACES = $0100
CompilerIf Defined(IP_ADDR_STRING, #PB_Structure) = 0
Structure IP_ADDR_STRING
*pNext
IpAddress.b[16]
IpMask.b[16]
Context.l
EndStructure
CompilerEndIf
CompilerIf Defined(IP_ADAPTER_INFO, #PB_Structure) = 0
Structure IP_ADAPTER_INFO
*Next
ComboIndex.l
AdapterName.b[#MAX_ADAPTER_NAME_LENGTH + 4]
Description.b[#MAX_ADAPTER_DESCRIPTION_LENGTH + 4]
AddressLength.l
Address.b[#MAX_ADAPTER_ADDRESS_LENGTH]
Index.l
Type.l
DhcpEnabled.l
*CurrentIpAddress.IP_ADDR_STRING
IpAddressList.IP_ADDR_STRING
GatewayList.IP_ADDR_STRING
DhcpServer.IP_ADDR_STRING
HaveWins.l
PrimaryWinsServer.IP_ADDR_STRING
SecondaryWinsServer.IP_ADDR_STRING
LeaseObtained.l
LeaseExpires.l
EndStructure
CompilerEndIf
Structure SOCKET_ADDRESS
*lpSockaddr
iSockaddrLength.l
EndStructure
Structure sockaddr_in6
sin6_family.w
sin6_port.w
sin6_flowinfo.l
sin6_addr.b[16]
sin6_scope_id.l
EndStructure
Structure MIB_IPADDRROW
dwAddr.l
dwIndex.l
dwMask.l
dwBCastAddr.l
dwReasmSize.l
unused1.w
wType.w
EndStructure
Structure MIB_IPADDRTABLE
dwNumEntries.l
table.MIB_IPADDRROW[0]
EndStructure
Structure IP_ADAPTER_PREFIX
Length.l
Flags.l
*Next
Address.SOCKET_ADDRESS
PrefixLength.l
EndStructure
Structure IP_ADAPTER_UNICAST_ADDRESS
Length.l
Flags.l
*Next;
Address.SOCKET_ADDRESS
PrefixOrigin.l
SuffixOrigin.l
DadState.l
ValidLifetime.l
PreferredLifetime.l
LeaseLifetime.l
OnLinkPrefixLength.b ;<-uint8?
EndStructure
Structure IP_ADAPTER_DNS_SERVER_ADDRESS ;Same for anycast and multicast
Length.l
Reserved.l
*Next
Address.SOCKET_ADDRESS
EndStructure
Structure IP_ADAPTER_ADDRESSES
Length.l
IfIndex.l
*Next
*AdapterName ;
*FirstUnicastAddress
*FirstAnycastAddress
*FirstMulticastAddress
*FirstDnsServerAddress
*DnsSuffix ;
*Description ;
*FriendlyName ;
PhysicalAddress.b[#MAX_ADAPTER_ADDRESS_LENGTH]
PhysicalAddressLength.l
Flags.l
Mtu.l
IfType.l
OperStatus.l ;?
Ipv6IfIndex.l
ZoneIndices.l[16]
*FirstPrefix
; TransmitLinkSpeed.q
; ReceiveLinkSpeed.q
; *FirstWinsServerAddress;.IP_ADAPTER_WINS_SERVER_ADDRESS_LH
; *FirstGatewayAddress;.IP_ADAPTER_GATEWAY_ADDRESS_LH
; Ipv4Metric.l
; Ipv6Metric.l
; Luid.IF_LUID
; Dhcpv4Server.SOCKET_ADDRESS
; CompartmentId.NET_IF_COMPARTMENT_ID
; NetworkGuid.NET_IF_NETWORK_GUID
; ConnectionType.l
; TunnelType.l
; Dhcpv6Server.SOCKET_ADDRESS
; Dhcpv6ClientDuid.b[#MAX_DHCPV6_DUID_LENGTH]
; Dhcpv6ClientDuidLength.l
; Dhcpv6Iaid.l
; *FirstDnsSuffix;.IP_ADAPTER_DNS_SUFFIX
EndStructure
Structure _ST_IF_ADAPINFO_
VTable.i
*pAdapterInfo.IP_ADAPTER_INFO
*pAdapterAddresses.IP_ADAPTER_ADDRESSES
*IpAddrTable.MIB_IPADDRTABLE
NumOfAdapters.l
GetAdaptersAddresses.__GetAdaptersAddresses
Lib.l
IPOffset.l
LastError.l
EndStructure
Interface _NETWORKADAPTERS_
CountAdapters()
CountIPAddresses(Num)
SelectIP(IP)
GetName.s(Num)
GetDescription.s(Num)
GetFriendlyName.s(Num)
GetMACAddress.s(Num)
GetIPAddress.s(Num, Index = 0)
GetSubnetMask.s(Num, Index = 0)
GetGateway.s(Num, Index = 0)
GetDHCPServer.s(Num)
GetType(Num)
GetIndex(Num)
UsesDHCP(Num)
DHCPObtained(Num)
DHCPExpires(Num)
AddIPAddress(Num, Address, SubnetMask = $FFFFFF)
DeleteIPAddress(Context)
Refresh()
Release()
EndInterface
Procedure IFNA_JumpToAdapter(*THIS._ST_IF_ADAPINFO_, Num)
;Internal Procedure...
Protected i, *Result, Offset
*Result = *THIS\pAdapterInfo
If Not *Result
Offset = OffsetOf(IP_ADAPTER_ADDRESSES\Next)
*Result = *THIS\pAdapterAddresses
EndIf
If Num > 0
For i = 1 To Num
*Result = PeekI(*Result + Offset)
If *Result = 0
Break
EndIf
Next i
EndIf
ProcedureReturn *Result
EndProcedure
Procedure.s IFNA_CalcSubnet(*THIS._ST_IF_ADAPINFO_, Index)
Protected Result.s
For i = 0 To *THIS\IpAddrTable\dwNumEntries - 1
If *THIS\IpAddrTable\table[i]\dwIndex = Index
Result = IPString(*THIS\IpAddrTable\table[i]\dwMask)
Break
EndIf
Next i
ProcedureReturn Result
EndProcedure
Procedure IFNA_CountAdapters(*THIS._ST_IF_ADAPINFO_)
;/-----------
;| Returns how many Adapters this computer has
;/-----------
ProcedureReturn *THIS\NumOfAdapters
EndProcedure
Procedure IFNA_SelectIP(*THIS._ST_IF_ADAPINFO_, IP)
Protected Result
Result = *THIS\IPOffset
Select IP
Case #SELECT_ANYCAST_ADDRESS
*THIS\IPOffset = OffsetOf(IP_ADAPTER_ADDRESSES\FirstAnycastAddress)
Case #SELECT_MULTICAST_ADDRESS
*THIS\IPOffset = OffsetOf(IP_ADAPTER_ADDRESSES\FirstMulticastAddress)
Case #SELECT_DNS_ADDRESS
*THIS\IPOffset = OffsetOf(IP_ADAPTER_ADDRESSES\FirstDnsServerAddress)
Default
*THIS\IPOffset = OffsetOf(IP_ADAPTER_ADDRESSES\FirstUnicastAddress)
EndSelect
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetName(*THIS._ST_IF_ADAPINFO_, Num)
;/------------
;| Get Name of Adapter Num
;| (This is mostly a GUID)
;/------------
Protected Result.s
Protected *pAdapter.IP_ADAPTER_ADDRESSES
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
If *THIS\pAdapterInfo
Result = PeekS(*pAdapter + OffsetOf(IP_ADAPTER_INFO\AdapterName), SizeOf(IP_ADAPTER_INFO\AdapterName), #PB_Ascii)
Else
Result = PeekS(*pAdapter\AdapterName, -1, #PB_Ascii)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetDescription(*THIS._ST_IF_ADAPINFO_, Num)
;/-----------
;| Get Description of Adapter Num
;| (Description is the readable name)
;/-----------
Protected Result.s
Protected *pAdapter.IP_ADAPTER_ADDRESSES
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
If *THIS\pAdapterInfo
Result = PeekS(*pAdapter + OffsetOf(IP_ADAPTER_INFO\Description), SizeOf(IP_ADAPTER_INFO\AdapterName), #PB_Ascii)
Else
Result = PeekS(*pAdapter\Description, -1, #PB_Unicode)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetFriendlyName(*THIS._ST_IF_ADAPINFO_, Num)
;/-----------
;| Get FriendlyName of Adapter Num (only >= WinXP)
;| (Description is the readable name)
;/-----------
Protected Result.s
Protected *pAdapter.IP_ADAPTER_ADDRESSES
If Num >= 0 And Num < *THIS\NumOfAdapters And *THIS\pAdapterAddresses
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
Result = PeekS(*pAdapter\FriendlyName, -1, #PB_Unicode)
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetMACAddress(*THIS._ST_IF_ADAPINFO_, Num)
;/----------
;| Get MAC-Address of Adapter Num
;/----------
Protected Result.s, i, Offset, Length
Protected *pAdapter
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
Result = ""
If *THIS\pAdapterInfo
Offset = OffsetOf(IP_ADAPTER_INFO\Address)
Length = PeekL(*pAdapter + OffsetOf(IP_ADAPTER_INFO\AddressLength))
Else
Offset = OffsetOf(IP_ADAPTER_ADDRESSES\PhysicalAddress)
Length = PeekL(*pAdapter + OffsetOf(IP_ADAPTER_ADDRESSES\PhysicalAddressLength))
EndIf
For i = 0 To Length - 1
Result + RSet(Hex(PeekB(*pAdapter + Offset + i) & $FF), 2, "0") + "-"
Next i
Result = Left(Result, Len(Result) - 1)
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_CountIPAddresses(*THIS._ST_IF_ADAPINFO_, Num)
;/----------
;| Count the IP Addresses of Adapter Num
;/----------
Protected Result, Offset
Protected *pAdapter.IP_ADAPTER_INFO, *nextip
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
If *THIS\pAdapterInfo
If *THIS\IPOffset = #SELECT_UNICAST_ADDRESS
*nextip = *pAdapter\IpAddressList
Offset = OffsetOf(IP_ADDR_STRING\pNext)
EndIf
Else
*nextip = PeekI(*pAdapter + *THIS\IPOffset)
Offset = OffsetOf(IP_ADAPTER_UNICAST_ADDRESS\Next)
EndIf
If *nextip
Repeat
Result + 1
If PeekI(*nextip + Offset) = 0
Break
Else
*nextip = PeekI(*nextip + Offset)
EndIf
ForEver
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_UsesDHCP(*THIS._ST_IF_ADAPINFO_, Num)
;/---------
;| Returns #True, when Adapter uses DHCP
;/---------
Protected Result
Protected *pAdapter.IP_ADAPTER_INFO
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
Result = *pAdapter\DhcpEnabled
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_DHCPObtained(*THIS._ST_IF_ADAPINFO_, Num)
;/---------
;| Datestamp, when DHCP has been obtained
;/---------
Protected Result
Protected *pAdapter.IP_ADAPTER_INFO
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
Result = *pAdapter\LeaseObtained
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_DHCPExpires(*THIS._ST_IF_ADAPINFO_, Num)
;/---------
;| Datestamp, when DHCP will expire
;/---------
Protected Result
Protected *pAdapter.IP_ADAPTER_INFO
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
Result = *pAdapter\LeaseExpires
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetIPAddress(*THIS._ST_IF_ADAPINFO_, Num, Index = 0)
;/----------
;| Get IP Addresses of this Adapter.
;| There can be more then one, thats why there is
;| the parameter Index.
;| You can check out how many IPs this Adapter has
;| when calling CountIPAdresses()
;/----------
Protected Result.s, a$, i, j, k, Offset, L
Protected *pAdapter.IP_ADAPTER_INFO, *nextip, *ipv4.SOCKADDR_IN, *ipv6.sockaddr_in6
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
If *THIS\pAdapterInfo
*nextip = *pAdapter\IpAddressList
Offset = OffsetOf(IP_ADDR_STRING\pNext)
Else
*nextip = PeekI(*pAdapter + *THIS\IPOffset)
Offset = OffsetOf(IP_ADAPTER_DNS_SERVER_ADDRESS\Next)
EndIf
If *nextip
For i = 1 To Index
If PeekI(*nextip + Offset)
*nextip = PeekI(*nextip + Offset)
Else
*nextip = 0
Break
EndIf
Next i
If *nextip
If *THIS\pAdapterInfo
Result = PeekS(*nextip + OffsetOf(IP_ADDR_STRING\IpAddress), SizeOf(IP_ADDR_STRING\IpAddress), #PB_Ascii)
Else
L = PeekL(*nextip + OffsetOf(IP_ADAPTER_DNS_SERVER_ADDRESS\Address) + OffsetOf(SOCKET_ADDRESS\iSockaddrLength))
If L = SizeOf(SOCKADDR_IN)
*ipv4 = PeekI(*nextip + OffsetOf(IP_ADAPTER_DNS_SERVER_ADDRESS\Address))
Result = IPString(*ipv4\sin_addr)
Else
*ipv6 = PeekI(*nextip + OffsetOf(IP_ADAPTER_DNS_SERVER_ADDRESS\Address))
For i = 0 To 15 Step 2
k = *ipv6\sin6_addr[i] & $FF
j = *ipv6\sin6_addr[i + 1] & $FF
If k > 0
Result + Hex(k)
EndIf
If j > 0
Result + Hex(j)
EndIf
If Right(Result, 2) <> "::"
Result + ":"
EndIf
Next i
Result = Left(Result, Len(Result) - 1) + "%" + Str(*ipv6\sin6_scope_id)
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetSubnetMask(*THIS._ST_IF_ADAPINFO_, Num, Index = 0)
;/----------
;| Get SubnetMask for this Adapter-IP
;| There can be more then one, thats why there is
;| the parameter Index.
;| You can check out how many IPs this Adapter has
;| when calling CountIPAdresses()
;/----------
Protected Result.s, i
Protected *pAdapter.IP_ADAPTER_INFO, *nextip.IP_ADDR_STRING, *pAdapter2.IP_ADAPTER_ADDRESSES
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
If *THIS\pAdapterInfo
*nextip = *pAdapter\IpAddressList
For i = 1 To Index
If *nextip\pNext
*nextip = *nextip\pNext
Else
*nextip = 0
Break
EndIf
Next i
If *nextip
Result = PeekS(*nextip + OffsetOf(IP_ADDR_STRING\IpMask), SizeOf(IP_ADDR_STRING\IpMask), #PB_Ascii)
EndIf
Else
*pAdapter2 = *pAdapter
Result = IFNA_CalcSubnet(*THIS, *pAdapter2\IfIndex)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetGateway(*THIS._ST_IF_ADAPINFO_, Num, Index = 0)
;/-----------
;| Get Gateway IP for this Adapter (if any)
;/-----------
Protected Result.s, i
Protected *pAdapter.IP_ADAPTER_INFO, *nextip.IP_ADDR_STRING
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
*nextip = *pAdapter\GatewayList
For i = 1 To Index
If *nextip\pNext
*nextip = *nextip\pNext
Else
*nextip = 0
Break
EndIf
Next i
If *nextip
Result = PeekS(*nextip + OffsetOf(IP_ADDR_STRING\IpAddress), SizeOf(IP_ADDR_STRING\IpAddress), #PB_Ascii)
EndIf
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s IFNA_GetDHCPServer(*THIS._ST_IF_ADAPINFO_, Num)
;/------------
;| Get IP of DHCP-Server
;| Value of "255.255.255.255" means there is
;| still a connection attempt running, or it is unreachable
;/------------
Protected Result.s
Protected *pAdapter.IP_ADAPTER_INFO, *nextip.IP_ADDR_STRING
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
*nextip = *pAdapter\DhcpServer
Result = PeekS(*nextip + OffsetOf(IP_ADDR_STRING\IpAddress), SizeOf(IP_ADDR_STRING\IpAddress), #PB_Ascii)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_GetType(*THIS._ST_IF_ADAPINFO_, Num)
;/----------
;| Returns Type of Adapter.
;| Possible values are:
;| #MIB_IF_TYPE_OTHER
;| #MIB_IF_TYPE_ETHERNET
;| #MIB_IF_TYPE_TOKENRING
;| #MIB_IF_TYPE_FDDI
;| #MIB_IF_TYPE_PPP
;| #MIB_IF_TYPE_LOOPBACK
;| #MIB_IF_TYPE_SLIP
;/----------
Protected Result, Offset = OffsetOf(IP_ADAPTER_ADDRESSES\IfType)
Protected *pAdapter
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
Offset = OffsetOf(IP_ADAPTER_INFO\Type)
EndIf
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
Result = PeekL(*pAdapter + Offset)
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_GetIndex(*THIS._ST_IF_ADAPINFO_, Num)
;/----------
;| Internal Index of Adapters.
;| Can change whenever Adapters are added or removed
;/----------
Protected Result
Protected *pAdapter.IP_ADAPTER_INFO
If Num >= 0 And Num < *THIS\NumOfAdapters
*pAdapter = IFNA_JumpToAdapter(*THIS, Num)
If *pAdapter
If *THIS\pAdapterInfo
Result = *pAdapter\Index
Else
Result = PeekL(*pAdapter + OffsetOf(IP_ADAPTER_ADDRESSES\IfIndex))
If Result = 0
Result = PeekL(*pAdapter + OffsetOf(IP_ADAPTER_ADDRESSES\Ipv6IfIndex))
EndIf
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_AddIPAddress(*THIS._ST_IF_ADAPINFO_, Num, Address, SubnetMask = $FFFFFF)
;/----------
;| Will try to add another [temporary] IP to the Adapter Num.
;| This only will succeed, when the cable is allready connected.
;|
;| The Result of this function has to be used as
;| parameter for DeleteIPAddress
;/----------
Protected Context, Index, Instance
If Num >= 0 And Num < *THIS\NumOfAdapters
If *THIS\pAdapterInfo
Index = IFNA_GetIndex(*THIS, Num)
*THIS\LastError = AddIPAddress_(Address, SubnetMask, Index, @Context, @Instance)
EndIf
EndIf
ProcedureReturn Context
EndProcedure
Procedure IFNA_DeleteIPAddress(*THIS._ST_IF_ADAPINFO_, Context)
;/----------
;| Delete the above set IP Address
;|
;| Returns #NO_ERROR on success
;/----------
Protected Result
*THIS\LastError = DeleteIPAddress_(Context)
ProcedureReturn *THIS\LastError
EndProcedure
Procedure IFNA_Refresh(*THIS._ST_IF_ADAPINFO_)
;/----------
;| Refresh all Adapter-Data
;/----------
Protected ulOutBufLen, Result, i
If *THIS\pAdapterInfo
FreeMemory(*THIS\pAdapterInfo)
*THIS\pAdapterInfo = #Null
EndIf
If *THIS\pAdapterAddresses
FreeMemory(*THIS\pAdapterAddresses)
*THIS\pAdapterAddresses = #Null
EndIf
If *THIS\IpAddrTable
FreeMemory(*THIS\IpAddrTable)
*THIS\IpAddrTable = #Null
EndIf
*THIS\NumOfAdapters = 0
If OSVersion() >= #PB_OS_Windows_XP And *THIS\GetAdaptersAddresses
*THIS\pAdapterAddresses = AllocateMemory(SizeOf(IP_ADAPTER_ADDRESSES))
*THIS\pAdapterAddresses\Length = SizeOf(IP_ADAPTER_ADDRESSES)
ulOutBufLen = SizeOf(IP_ADAPTER_ADDRESSES)
Result = *THIS\GetAdaptersAddresses(#AF_UNSPEC, #GAA_FLAG_INCLUDE_PREFIX | #GAA_FLAG_INCLUDE_ALL_INTERFACES, #Null, *THIS\pAdapterAddresses, @ulOutBufLen)
If Result = #ERROR_BUFFER_OVERFLOW
*THIS\pAdapterAddresses = ReAllocateMemory(*THIS\pAdapterAddresses, ulOutBufLen)
Result = *THIS\GetAdaptersAddresses(#AF_UNSPEC, 0, #Null, *THIS\pAdapterAddresses, @ulOutBufLen)
EndIf
If Result = #NO_ERROR
While IFNA_JumpToAdapter(*THIS, *THIS\NumOfAdapters)
*THIS\NumOfAdapters + 1
Wend
*THIS\IpAddrTable = AllocateMemory(SizeOf(MIB_IPADDRTABLE))
ulOutBufLen = SizeOf(MIB_IPADDRTABLE)
Result = GetIpAddrTable_(*THIS\IpAddrTable, @ulOutBufLen, #True)
If Result = #ERROR_INSUFFICIENT_BUFFER
*THIS\IpAddrTable = ReAllocateMemory(*THIS\IpAddrTable, ulOutBufLen)
Result = GetIpAddrTable_(*THIS\IpAddrTable, @ulOutBufLen, #True)
EndIf
EndIf
EndIf
If *THIS\pAdapterAddresses = #Null
*THIS\pAdapterInfo = AllocateMemory(SizeOf(IP_ADAPTER_INFO))
ulOutBufLen = SizeOf(IP_ADAPTER_INFO);
Result = GetAdaptersInfo_(*THIS\pAdapterInfo, @ulOutBufLen)
If Result = #ERROR_BUFFER_OVERFLOW
*THIS\pAdapterInfo = ReAllocateMemory(*THIS\pAdapterInfo, ulOutBufLen)
Result = GetAdaptersInfo_(*THIS\pAdapterInfo, @ulOutBufLen)
EndIf
If Result = #NO_ERROR
While IFNA_JumpToAdapter(*THIS, *THIS\NumOfAdapters)
*THIS\NumOfAdapters + 1
Wend
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure IFNA_Release(*THIS._ST_IF_ADAPINFO_)
;/----------
;| Will release the Interface and all of its used Memory.
;|
;| !!ATTENTION!!
;| Your Pointer to the Interface will be invalid after
;| calling Release()!
;| So it should only be used at end of program.
;/----------
If *THIS\pAdapterInfo
FreeMemory(*THIS\pAdapterInfo)
EndIf
If *THIS\pAdapterAddresses
FreeMemory(*THIS\pAdapterAddresses)
EndIf
If *THIS\IpAddrTable
FreeMemory(*THIS\IpAddrTable)
EndIf
If *THIS\Lib
CloseLibrary(*THIS\Lib)
EndIf
FreeMemory(*THIS)
EndProcedure
Procedure CreateNetworkAdapterInterface(ForceAdapterInfo = #False)
;/----------
;| The Interface creating procedure
;/----------
Protected *THIS._ST_IF_ADAPINFO_
If OSVersion() < #PB_OS_Windows_2000
ProcedureReturn #False
EndIf
*THIS = AllocateMemory(SizeOf(_ST_IF_ADAPINFO_))
*THIS\VTable = ?_VT_IFNA_DATA_
If *THIS = 0
ProcedureReturn #False
EndIf
*THIS\GetAdaptersAddresses = #Null
*THIS\Lib = #Null
*THIS\IPOffset = OffsetOf(IP_ADAPTER_ADDRESSES\FirstUnicastAddress)
If ForceAdapterInfo = #False And OSVersion() >= #PB_OS_Windows_XP
*THIS\Lib = OpenLibrary(#PB_Any, "Iphlpapi.dll")
If *THIS\Lib
*THIS\GetAdaptersAddresses = GetFunction(*THIS\Lib, "GetAdaptersAddresses")
If *THIS\GetAdaptersAddresses = 0
CloseLibrary(*THIS\Lib)
*THIS\Lib = #Null
EndIf
EndIf
EndIf
If IFNA_Refresh(*THIS) <> #NO_ERROR
If *THIS\pAdapterInfo
FreeMemory(*THIS\pAdapterInfo)
EndIf
If *THIS\pAdapterAddresses
FreeMemory(*THIS\pAdapterAddresses)
EndIf
If *THIS\IpAddrTable
FreeMemory(*THIS\IpAddrTable)
EndIf
FreeMemory(*THIS)
*THIS = 0
EndIf
ProcedureReturn *THIS
EndProcedure
DataSection
_VT_IFNA_DATA_:
Data.i @IFNA_CountAdapters()
Data.i @IFNA_CountIPAddresses()
Data.i @IFNA_SelectIP()
Data.i @IFNA_GetName()
Data.i @IFNA_GetDescription()
Data.i @IFNA_GetFriendlyName()
Data.i @IFNA_GetMACAddress()
Data.i @IFNA_GetIPAddress()
Data.i @IFNA_GetSubnetMask()
Data.i @IFNA_GetGateway()
Data.i @IFNA_GetDHCPServer()
Data.i @IFNA_GetType()
Data.i @IFNA_GetIndex()
Data.i @IFNA_UsesDHCP()
Data.i @IFNA_DHCPObtained()
Data.i @IFNA_DHCPExpires()
Data.i @IFNA_AddIPAddress()
Data.i @IFNA_DeleteIPAddress()
Data.i @IFNA_Refresh()
Data.i @IFNA_Release()
EndDataSection
Code: Alles auswählen
XIncludeFile "NetworkAdapterInterface_V02.pbi"
Procedure.s TypeToString(Type)
Protected Result.s
Select Type
Case #MIB_IF_TYPE_OTHER : Result = "other type of network interface"
Case #MIB_IF_TYPE_ETHERNET : Result = "Ethernet network interface"
Case #MIB_IF_TYPE_TOKENRING : Result = "token ring network interface"
Case #MIB_IF_TYPE_FDDI : Result = "FDDI"
Case #MIB_IF_TYPE_PPP : Result = "PPP network interface"
Case #MIB_IF_TYPE_LOOPBACK : Result = "software loopback network interface"
Case #MIB_IF_TYPE_SLIP : Result = "Slip"
Case #IF_TYPE_ATM : Result = "ATM network interface"
Case #IF_TYPE_IEEE80211 : Result = "IEEE 802.11 wireless network interface"
Case #IF_TYPE_TUNNEL : Result = "tunnel type encapsulation network interface"
Case #IF_TYPE_IEEE1394 : Result = "IEEE 1394 (Firewire) high performance serial bus network interface"
EndSelect
ProcedureReturn Result
EndProcedure
Procedure main()
Protected i, j, k, l, a$
Protected NetAd._NETWORKADAPTERS_
Dim MyIPs.s(4)
MyIPs(0) = "UNICAST IPs:"
MyIPs(1) = "ANYCAST IPs:"
MyIPs(2) = "MULTICAST IPs:"
MyIPs(3) = "DNS IPs:"
NetAd = CreateNetworkAdapterInterface()
If NetAd = 0
Debug "Error!"
End
EndIf
For i = 0 To NetAd\CountAdapters() - 1
Debug "Number " + Str(i + 1) + " (Index:" + Str(NetAd\GetIndex(i)) + ")"
Debug "--------"
Debug "Type: " + TypeToString(NetAd\GetType(i))
Debug "Name: " + NetAd\GetName(i)
Debug "FriendlyName: " + NetAd\GetFriendlyName(i)
Debug "Desc: " + NetAd\GetDescription(i)
Debug "MAC : " + NetAd\GetMACAddress(i)
For l = 0 To 3
NetAd\SelectIP(l)
j = NetAd\CountIPAddresses(i)
If j
Debug MyIPs(l) + Str(j)
For k = 0 To j - 1
a$ = NetAd\GetIPAddress(i, k)
Debug "IP#" + Str(k + 1) + ": " + a$
If FindString(a$, ".", 1)
Debug "Subnet#" + Str(k + 1) + ": " + NetAd\GetSubnetMask(i, k)
EndIf
Next k
EndIf
Next l
Debug "Gateway: " + NetAd\GetGateway(i)
If NetAd\UsesDHCP(i)
Debug "uses DHCP!"
Debug "DHCP Server: " + NetAd\GetDHCPServer(i)
Debug "DHCP obtained: " + FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", NetAd\DHCPObtained(i))
Debug "DHCP expires: " + FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", NetAd\DHCPExpires(i))
EndIf
Debug ""
Next i
NetAd\Release()
EndProcedure
main()