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) < 0then 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 := 0to len - 1do begin fillchar(ifr, sizeof(ifreq), 0); //считать очередную порцию данных move(pifr^, ifr, sizeof(ifreq));