Информация о сетевых интерфейсах
Информация о сетевых интерфейсах
unitnetinfo;
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
Автор