unit Winapi.NetworkInterfaces;
interface
uses
IdWinsock2;
type
tNetworkInterface =
record
AddrIP:
string;
SubnetMask:
string;
AddrNet:
string;
AddrLimitedBroadcast:
string;
AddrDirectedBroadcast:
string;
IsInterfaceUp: Boolean;
BroadcastSupport: Boolean;
IsLoopback: Boolean;
IsPointToPoint: Boolean;
IsMulticast: Boolean;
end;
tNetworkInterfaceList =
array of tNetworkInterface;
function GetNetworkInterfaces( ): tNetworkInterfaceList;
implementation
uses
Winapi.Errors;
procedure RaiseLastWinsocket2Error(
const AdditionalInfo:
string = '
' );
begin
RaiseLastModuleError( WinsockHandle( ), WSAGetLastError( ), AdditionalInfo );
end;
function GetNetworkInterfaces( ): tNetworkInterfaceList;
var
aSocket : TSocket;
NoOfInterfaces : Integer;
NoOfBytesReturned : u_Long;
InterfaceFlags : u_Long;
pAddrIP : sockaddr_in;
pAddrSubnetMask : sockaddr_in;
pAddrBroadcast : sockaddr_in;
pIPString : PAnsiChar;
pSubnetMaskString : PAnsiChar;
pLimBroadcastString: PAnsiChar;
pNetAddrString : PAnsiChar;
pDirBroadcastString: PAnsiChar;
DirBroadcastDummy : In_Addr;
NetAddrDummy : In_Addr;
Buffer :
array [ 0 .. 30 ]
of interface_info;
cbOutBuffer : u_Long;
i : Integer;
begin
InitializeWinSock;
SetLength( Result, 0 );
aSocket := Socket( AF_INET, SOCK_STREAM, 0 );
if ( aSocket = INVALID_SOCKET )
then
RaiseLastWinsocket2Error( );
try
cbOutBuffer := Length( Buffer ) * SizeOf( interface_info );
if WSAIoctl( aSocket, SIO_GET_INTERFACE_LIST,
nil, 0, @Buffer, cbOutBuffer, @NoOfBytesReturned,
nil,
nil ) <> 0
then
RaiseLastWinsocket2Error( );
NoOfInterfaces := NoOfBytesReturned
div SizeOf( interface_info );
SetLength( Result, NoOfInterfaces );
// For each of the identified interfaces get:
for i := 0
to NoOfInterfaces - 1
do
begin
with Result[ i ]
do
begin
// Get the IP address
pAddrIP := Buffer[ i ].iiAddress.AddressIn;
pIPString := inet_ntoa( pAddrIP.sin_addr );
AddrIP :=
string( pIPString );
// Get the subnet mask
pAddrSubnetMask := Buffer[ i ].iiNetmask.AddressIn;
pSubnetMaskString := inet_ntoa( pAddrSubnetMask.sin_addr );
SubnetMask :=
string( pSubnetMaskString );
// Get the limited broadcast address
pAddrBroadcast := Buffer[ i ].iiBroadcastAddress.AddressIn;
pLimBroadcastString := inet_ntoa( pAddrBroadcast.sin_addr );
AddrLimitedBroadcast :=
string( pLimBroadcastString );
// Calculate the net and the directed broadcast address
NetAddrDummy.S_addr := Buffer[ i ].iiAddress.AddressIn.sin_addr.S_addr;
NetAddrDummy.S_addr := NetAddrDummy.S_addr
and Buffer[ i ].iiNetmask.AddressIn.sin_addr.S_addr;
DirBroadcastDummy.S_addr := NetAddrDummy.S_addr
or not Buffer[ i ].iiNetmask.AddressIn.sin_addr.S_addr;
pNetAddrString := inet_ntoa( ( NetAddrDummy ) );
AddrNet :=
string( pNetAddrString );
pDirBroadcastString := inet_ntoa( ( DirBroadcastDummy ) );
AddrDirectedBroadcast :=
string( pDirBroadcastString );
// From the evaluation of the Flags we receive more information
InterfaceFlags := Buffer[ i ].iiFlags;
IsInterfaceUp := ( InterfaceFlags
and IFF_UP ) = IFF_UP;
BroadcastSupport := ( InterfaceFlags
and IFF_BROADCAST ) = IFF_BROADCAST;
IsLoopback := ( InterfaceFlags
and IFF_LOOPBACK ) = IFF_LOOPBACK;
IsPointToPoint := ( InterfaceFlags
and IFF_POINTTOPOINT ) = IFF_POINTTOPOINT;
IsMulticast := ( InterfaceFlags
and IFF_MULTICAST ) = IFF_MULTICAST;
end;
end;
finally
CheckModuleError( CloseSocket( aSocket ), WinsockHandle( ) );
end;
end;
initialization
finalization
UninitializeWinSock;
end.