Информация о сетевых интерфейсах 

Previous  Top  Next

    
 

 

 

Code:

unit netinfo;

 

interface

uses Libc;

 

type

INTERFACE_INFO = packed record

   Name: string;

   IPAddress: string;

   Broadcast: string;

   NetMask: string;

   IsUp: boolean;

   IsRun: boolean;

   IsBroadcast: boolean;

   IsMulticast: boolean;

   IsLoopBack: boolean;

   IsPPP: boolean;

end;

 

TAInfo = record

   INFO: array of INTERFACE_INFO;

end;

 

function EnumInterfaces(var IInfo: TAInfo): Boolean;

 

implementation

 

function EnumInterfaces(var IInfo: TAInfo): Boolean;

var SHandle: integer;

len: longint;

bufChar;

ifc: ifconf;

pifr: pifreq;

ifr: ifreq;

lastlen, i: integer;

pAddrChar;

begin

Result := False;

//создать UDP сокет

SHandle := Socket(AF_INET, SOCK_DGRAM, 0);

if SHandle = INVALID_SOCKET then exit;

 

{

При вызове SIOCGIFCONF некоторые реализации

не возвращают ошибок, если буфер слишком мал

для хранения результата вызова (результат просто обрезается)

Поэтому надо сделать вызов, запомнить возвращенную длину,

увеличить буфер и сделать еще один вызов

ксли после этого вызова длины будут равны - OK!

иначе надо циклично увеличивать буфер.

}

lastlen := 0;

len := 100 * sizeof(ifreq);

 

while true do

   begin

     buf := Malloc(len);

     ifc.ifc_len := len;

     PChar(ifc.ifc_ifcu) := buf;

     if ioctl(SHandle, SIOCGIFCONF, @ifc) < 0 then

       begin

         if (errno <> EINVAL) and (lastlen <> 0) then

           warn('ioctl error');

       end

     else

       begin

         if ifc.ifc_len = lastlen then break;

         lastlen := ifc.ifc_len;

       end;

     len := len + 10 * sizeof(ifreq);

     free(buf);

   end;

Result := True;

//здесь результат получен полностью

//len - кол-во интерфейсов

len := ifc.ifc_len div sizeof(ifreq);

SetLength(IInfo.Info, len);

 

//указатель - на начало буфера

pifr := ifc.ifc_ifcu.ifcu_req;

for i := 0 to len - 1 do

   begin

     fillchar(ifr, sizeof(ifreq), 0);

//считать очередную порцию данных

     move(pifr^, ifr, sizeof(ifreq));

 

//имя интерфейса

     IInfo.INFO[i].Name := ifr.ifrn_name;

//адрес интерфейса

     pAddr := inet_ntoa(ifr.ifru_addr.sin_addr);

     IInfo.INFO[i].IPAddress := pAddr;

 

//ШВ адрес

     ioctl(SHandle, SIOCGIFBRDADDR, @ifr);

     pAddr := inet_ntoa(ifr.ifru_netmask.sin_addr);

     IInfo.INFO[i].Broadcast := pAddr;

 

//маска сети

     ioctl(SHandle, SIOCGIFNETMASK, @ifr);

     pAddr := inet_ntoa(ifr.ifru_netmask.sin_addr);

     IInfo.INFO[i].NetMask := pAddr;

 

//флаги

     ioctl(SHandle, SIOCGIFFLAGS, @ifr);

 

     IInfo.INFO[i].IsUP := (ifr.ifru_flags and IFF_UP) = IFF_UP;

     IInfo.INFO[i].IsRun := (ifr.ifru_flags and IFF_RUNNING) = IFF_RUNNING;

     IInfo.INFO[i].IsBroadcast := (ifr.ifru_flags and IFF_BROADCAST) = IFF_BROADCAST;

     IInfo.INFO[i].IsLoopBack := (ifr.ifru_flags and IFF_LOOPBACK) = IFF_LOOPBACK;

     IInfo.INFO[i].IsPPP := (ifr.ifru_flags and IFF_POINTOPOINT) = IFF_POINTOPOINT;

     IInfo.INFO[i].IsMulticast := (ifr.ifru_flags and IFF_MULTICAST) = IFF_MULTICAST;

 

     inc(pifr);

   end;

 

end;

end.

 

 

 

Взято с Исходников.Ru

Автор pve

 

©Drkb::04621