Delphi - база знаний

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


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




unitnetinfo;

interface
uses Libc;

type


  INTERFACE_INFO = packed record
    Namestring;
    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







Содержание раздела